====== kkormsvr ======
Модуль управления процессом многокомпонентного дозирования. Предназначен для замены старого приложения ''kkormrcpsvr2.exe''. Данный модуль требует включения в задачу.
===== Поддерживаемые модули дозаторов =====
[[doc:jroboplc:modules:peripherial:promauto_gelios_dozkkmc]]
===== Основные отличия от kkormrcpsvr2.exe =====
* Опрос дозаторов и управление процессом дозирования выполняют независимые друг от друга модули. Добавление нового типа дозатора в ''peripherial'' не требует изменения программного кода модуля ''kkormsvr''.
* Возможность размещаться как на сервере (старый вариант), так и в составе ПЛК с использованием сервера в качестве удаленного СУБД. Работа на одной аппаратной платформе с ПЛК позволяет отказаться от дискретных сигналов управления дозаторами без ущерба общей скорости дозирования.
* Хранение оперативных данных в базе данных, т.е. там же где и хранятся все остальные данные. Старый вариант использовал для сохранения оперативных данных обычные файлы, что в случае сбоя может привести к рассинхронизации. Другой минус старого варианта при использовании на борту ПЛК - это частые операции записи в файл, что также является потенциально опасным.
* В ситуации когда на линии несколько дозаторов, а по рецепту используются не все, то в неиспользуемые дозаторы не посылается нулевой рецепт, как это делал ''kkormrcpsvr2''. Также ''Kkormsvr'' для выполнения задачи не требует наличия связи с неиспользуемыми дозаторами.
* Работа одной транзакцией на цикл, что гарантирует целостность данных и положительно влияет на производительность приложения.
* Возможность отключения, включения и перезагрузки ''kkormsvr'' без прерывания выполнения задачи дозирования.
* При потери связи с удаленным СУБД восстановление происходит автоматически без прерывания выполнения задачи дозирования.
* Состав и именование тегов полностью обновлено. Новые теги кроме текущего состояния процесса также позволяют видеть названия рецептов и продуктов, выполнять сброс и приостановку работы линий.
При работе с удаленными модулями дозаторов использовать протокол [[doc:jroboplc:modules:jrbustcp]]!
Например, в //jrobo 1// работает ''roboplant'' логика и выполняется опрос всех устройств ввода/вывода (''peripherial''), в т.ч. и многокомпонентных дозаторов, а также работает модуль [[doc:jroboplc:modules:jrbustcp]] в режиме ''server''. В //jrobo 2// работает модуль ''kkormsvr'', взаимодействуя с локальной, либо удаленной базой данных, а теги по дозаторам поставляются при помощи модуля [[doc:jroboplc:modules:jrbustcp]] в режиме ''client''. Использовать связку ''rpsvrtcp'' и ''rpclient'' недопустимо, т.к. данный протокол не поддерживает передачу тегов типа ''LONG''.
Структура базы данных осталась прежней [[doc:jroboplc:modules:kkormsvr_db_model]]. При миграции старой системы на ''kkormsvr'' НЕЛЬЗЯ работать непосредственно со старой базой как есть, а необходимо создать новую и сделать [[doc:jroboplc:modules:kkormsvr#Переходный импорт данных|импорт]].
===== Конфигурация =====
plugin.kkormsvr:
module.kksvr:
database: db
lines:
- linenum: 1
name: "Линия 1"
dosers:
- name: "d1"
bind: "D001"
grouplevel: 0
storages:
1: 101, Бункер 101
2: 102, Бункер 102
3: 103, Бункер 103
- name: "d2"
storages:
1: 201
2: 202
3: 203
===== Параметры =====
^ Параметр ^ Умолчание ^ Описание ^
|**database**| ''db'' |Модуль базы данных ([[doc:jroboplc:modules:database]]) |
|**lines**| '''' |Список линий |
|**dosers**| '''' |Список дозаторов, принадлежащих линии |
|**storages**| '''' |Список бункеров/питателей, принадлежащих дозатору |
^lines ^^^
|**linenum**| ''0'' |Номер линии |
|**name**| ''Line'' |Название линии |
^dosers ^^^
|**name**| '''' |Имя дозатора. Используется для формирование имен тегов |
|**bind**| '''' |Имя peripherial-модуля многокомпонентного дозатора |
|**grouplevel**| ''0'' |Указывает принадлежность дозатора к группе с заданным уровнем опережения выполнения циклов. Отсчет уровня от нуля |
^storages ^^^
|****| |Формат записи: ''**stornum [, storname]**'', где
addr - адрес питателя в дозаторе (число)
stornum - уникальный номер бункера (число), соответствующего питателю дозатора
storname - название бункера (текст). Если не указывать, то будет //''Бункер ''// |
===== Теги =====
^ Имя тега ^ Тип данных ^ Доступ ^ Описание ^
|kksvr.connected | BOOL | |Подключение к базе данных. |
^Линия 1 ^^^^
|kksvr.Line1.CycleCnt | INT | |Количество выполненных полных циклов. |
|kksvr.Line1.CycleReq | INT | rw |Заданное количество циклов. |
|kksvr.Line1.State | INT | |Состояние линии:
0 - остановлено
1 - работа
2 - работа приостановлена
3 - ошибка: новая задача не распределилась между дозаторами
4 - ошибка: один из дозаторов не принял задачу
|
|kksvr.Line1.TaskId | INT | |''TaskId'' текущей задачи из таблицы ''KK_TASK''. Если задача отсутствут, равно 0. |
|kksvr.Line1.Receipt | STRING | |Название рецепта текущей задачи. |
|kksvr.Line1.Reset | BOOL | rw |1 - Сброс линии. |
|kksvr.Line1.Suspend | BOOL | rw |1 - Приостановить работу линии. 0 - возобновить. |
^Линия 1 - Группа 0 ^^^^
|kksvr.Line1.Group0.CycleCnt | INT | |Количество выполненных циклов. |
|kksvr.Line1.Group0.State | INT | |Состояние группы:
0 - остановлено
1 - подача дозаторам команды "Старт цикла". Ожидание готовности к установке задачи.
2 - установка задачи
3 - дозирование
4 - ошибка установки задачи одним из дозаторов. Какой именно дозатор - смотреть тег дозатора SendTask на отрицательное значение.
|
^Линия 1 - Группа 1 ^^^^
|kksvr.Line1.Group1.CycleCnt | INT | | ---\\--- |
|kksvr.Line1.Group1.State | INT | | ---\\--- |
^Линия 1 - Дозатор d1 ^^^^
|kksvr.d1.CurStorNum | INT | | номер ''stornum'' текущего бункера |
|kksvr.d1.CurStorName | STRING | |название ''name'' текущего бункера |
|kksvr.d1.CurProduct | STRING | |название текущего загружаемого продукта |
|kksvr.d1.Error | INT | |Текущая ошибка работы с дозатором (не путать с кодом ошибки самого дозатора):
0 - ошибки нет
1 - LINK - теги дозатора не найдены (проверить, есть ли теги, правильность параметра ''bind'')
2 - DISCONNECT - нет связи
3 - CRC - данные не достоверны
4 - TASKDIFFER - заданный вес в дозаторе отличается от заданного по рецепту
|
|kksvr.d1.ReqWeightZero | INT | | =1, если суммарный заданный вес равен нулю, иначе =0 |
|kksvr.d1.Product1 | STRING | |Название продукта, заданного по рецепту. |
|kksvr.d1.ReqWeight1 | LONG | |Заданный вес по рецепту. |
|kksvr.d1.Product2 | STRING | | ---\\--- |
|kksvr.d1.ReqWeight2 | LONG | | ---\\--- |
|kksvr.d1.Product3 | STRING | | ---\\--- |
|kksvr.d1.ReqWeight3 | LONG | | ---\\--- |
^Линия 1 - Дозатор d2 ^^^^
|kksvr.d2.CurStorNum | INT | | ---\\--- |
|kksvr.d2.CurStorName | STRING | | ---\\--- |
|kksvr.d2.CurProduct | STRING | | ---\\--- |
|kksvr.d2.Error | INT | | ---\\--- |
|kksvr.d1.ReqWeightZero | INT | | ---\\--- |
|kksvr.d2.Product1 | STRING | | ---\\--- |
|kksvr.d2.ReqWeight1 | LONG | | ---\\--- |
|kksvr.d2.Product2 | STRING | | ---\\--- |
|kksvr.d2.ReqWeight2 | LONG | | ---\\--- |
|kksvr.d2.Product3 | STRING | | ---\\--- |
|kksvr.d2.ReqWeight3 | LONG | | ---\\--- |
[[doc:jroboplc:modules:kkormsvr_old_tags]]
===== Группы =====
Процесс приготовления комбикормовой смеси может происходить в несколько этапов.
Например, некоторые добавки могут предварительно дозироваться и смешиваться (в предсмесителе) отдельно от основной массы ингредиентов. Затем они выгружаются в основной смеситель одновременно с разгрузкой дозаторов, дозирующих основные ингредиенты.
В таком случае для ускорения цикла приготовления комбикормовой смеси целесообразно разрешить дозаторам, разгрузка которых происходит в предсмеситель, набирать продукт заранее. Т.е. если линия выполняет первый цикл дозирования - дозаторы основного смесителя выполняют первый цикл, то дозаторы предсмесителя могут выполнять первый и (если все они выгрузились) второй цикл дозирования.
Параметр ''grouplevel'' определяет на сколько циклов дозирования группа может «обгонять» цикл дозирования линии.
В группу целесообразно объединять ДОЗАТОРЫ ОДНОВРЕМЕННО РАЗГРУЖАЕМЫЕ В ОДИН СМЕСИТЕЛЬ.
Для дозаторов группы которая заканчивает процесс приготовления комбикормовой смеси (или если группа одна) параметр ''grouplevel'' должен быть равен 0.
===== Дозирование вне задачи =====
Во время выполнения задачи каждое изменение значения суммарного счетчика дозатора (другими словами - отвес) фиксируется в базе данных в соответствующих таблицах с ссылкой на задачу и рецепт, по которому работает задача. Если же счетчики меняют значение, когда линия остановлена и выполняемых задач нет, то в этой ситуации создается задача с пустым рецептом, и уже к ней привязывается отвес. Пустой рецепт создается автоматически с названием "ДОЗИРОВАНИЕ ВНЕ ЗАДАЧИ (РУЧНОЕ)" и kk_receipt.id равным 0.
Также при фиксировании отвеса вне задачи указывается продукт, который в данный момент назначен соответствующему бункеру. Если продукт не указан, создается "НЕИЗВЕСТНЫЙ ПРОДУКТ" c kk_product.id равным 0.
===== Переходный импорт данных =====
Для перехода со старого архиватора ''kkormrcpsvr2'' на новый требуется перенести данные из старой базы данных в новую, создаваемою автоматически модулем ''kkormsvr''. Описание действий по шагам:
* создать два модуля ''database'' для подключения к новой (не существующей) и старой (существующей) базам данных.
plugin.database:
module.db:
type: firebird
dbname: /database/kkorm_fb30.fdb
module.dbold:
type: firebird
dbname: /database/old_kkorm_fb30.fdb
plugin.kkormsvr:
module.kksvr:
database: db
plugin.task:
module.taskmain:
modules:
- db
- kksvr
* запустить систему и выполнить команды:
kksvr:import dbold
reload kksvr
Данный способ перехода является рекомендуемым, т.к. новая база будет избавлена от ненужных артефактов, накопленных годами. Также в новой базе добавлены таблицы оперативных данных и оптимизированы индексы некоторых таблиц.
===== Удаление старых записей =====
В таблицах ''KK_TASK'', ''KK_TASKCONTENT'', ''KK_EXECUTE'', ''KK_OUTPUT'' и ''KK_RASHOD'' данные сохраняются без циклической перезаписи, и таким образом постоянно накапливаются. Для удаления ненужных данных используется команда ''w:sweep ''. Пример использования:
kksvr:sweep 2016
Данная команда, посылаемая модулю с именем ''kksvr'', удаляет все записи старше 2016 года включительно.