# kkmansvr

Модуль управления процессом ручного многокомпонентного дозирования. Данный модуль требует включения в задачу.

## Поддерживаемые модули дозаторов

promauto.gelios.dozman

## Конфигурация

    plugin.kkmansvr:

      module.kkman:
        emulate:  off
        database: db
        lineId:   1
        lineName: My line
        compQnt:  4
        dosers:
          - name:        d1
            descr:       Big automatic doser
            manual:      off
            canControl:  on

          - name:        d2
            descr:       Small human-being driven doser
            manual:      on
            canControl:  off

## Параметры

Параметр | Умолчание | Описание
--- | --- | ---
database | `db` | Модуль базы данных (database)
lineId | `` | id линии
lineName | `Line<lineId>` | Название линии (произвольный текст)
compQnt | `` | Максимальное количество компонентов в задаче
dosers | `` | Список дозаторов
dosers
name | `` | Имя периферийного модуля дозатора
descr | `` | Название дозатора (произвольный текст)
manual | `off` | Ручной дозатор
canControl | `off` | Дозатор может использоваться как контрольный

## Теги

Имя тега | Тип данных | Доступ | Описание
--- | --- | --- | ---
`LineId` | `INT` | `` | id линии (`KM_LINE.ID`)
`LineName` | `STRING` | `` | Название линии
`TaskInstall` | `STRING` | `RW` | см. Установка задачи
`TaskId` | `INT` | `` | id задачи (`KM_TASK.ID`)
`RecipeId` | `INT` | `` | id рецепта (`KM_TASK.RECIPE.ID`)
`RecipeName` | `STRING` | `` | Название рецепта (`KM_RECIPE.NAME`)
`CycleReq` | `INT` | `RW` | Заданное количество циклов. Если `CycleReq`>0 и `СусleCnt`>=`CycleReq`, то запуск нового цикла невозможен. Если =0, то работать без ограничений. CycleReq можно менять в процессе работы
`CycleCnt` | `INT` | `` | Кол-во выполненных циклов
`UnloadStart` | `BOOL` | `` | Команда старт оборудованию разгрузки
`UnloadFinished` | `BOOL` | `RW` | Сигнал завершения от оборудования разгрузки
`UnloadTimerCnt` | `INT` | `` | Счетчик задержки разгрузки. Если `UnloadTimerCnt` < `UnloadTimerSet`, то `UnloadFinished` считается =0
`UnloadTimerSet` | `INT` | `RW` | Минимальное время разгрузки (ед.изм. - кол-во циклов jrobo-задачи)
`Status` | `INT` | `` | См. Статус линии
`SumWeightReq` | `INT` | `` | Заданный в задаче суммарный вес по всем компонентам
`SumWeightFin` | `INT` | `` | Зафиксированный суммарный вес по всем компонентам
`SumWeightCtl` | `INT` | `` | Зафиксированный контрольный вес
`ControlId` | `INT` | `` | id контрольного дозатора (далее `ControlDoser`). Если 0, то не используется
`ControlName` | `STRING` | `` | Имя модуля контрольного дозатора. Если пусто, то не используется. Если `NOT FOUND`, то модуль с `ControlId` не найден
`ControlStable` | `BOOL` | `` | Транслируется значение с `ControlDoser.Stable`
`ControlWeight` | `INT` | `` | Транслируется значение с `ControlDoser.WeightTot`
`Run` | `BOOL` | `RW` | Если записать 1, то начать весовой цикл. Нельзя извне `Run=0`. Если `TaskId=0`, то нельзя `Run=1`. Нельзя `Run=1`, если `Disable=1`.
`Disable` | `BOOL` | `RW` | Запрет начала весового цикла. Нельзя `Disable=1`, если `Run=1`
`Commit` | `BOOL` | `RW` | Записать весовой цикл в базу данных и перейти к разгрузке
`Cancel` | `BOOL` | `RW` | Отменить весовой цикл. Сбрасываются все зафиксированные весовые значения
Компоненты
`Comp0.DoserId` | `INT` | `` | id дозатора компонента (далее `CompDoser`) (`KM_TASK_PRODUCT.DOSER_ID`)
`Comp0.DoserName` | `STRING` | `` | Имя модуля дозатора
`Comp0.Manual` | `BOOL` | `` | Ручной дозатор
`Comp0.ProdId` | `INT` | `` | id продукта (`KM_TASK_PRODUCT.PRODUCT_ID`)
`Comp0.ProdName` | `STRING` | `` | Название продукта (`KM_PRODUCT.NAME`)
`Comp0.WeightReq` | `INT` | `` | Заданный вес
`Comp0.WeightFin` | `INT` | `` | Зафиксированный измеренный вес
`Comp0.WeightCur` | `INT` | `` | Транслируется значение с `CompDoser.WeightCur`
`Comp0.Status` | `INT` | `` | См. Статус компонента
`Comp0.Run` | `BOOL` | `RW` | Если записать 1, то начать дозирование. Нельзя извне `Run=0`. Обнуление происходит по окончанию дозирования. Установка возможна только при `Comp*.Status=IDLE` по всем компонентам с таким же `DoserId` и при статусе линии `=LOADING`
`Comp0.Cancel` | `BOOL` | `RW` | Отменить зафиксированный вес и перейти в ожидание
остальные `Comp1..CompN` аналогично

## База данных

Скрипт

База данных создается автоматически. Данные по линии и дозаторам автоматически добавляются в таблицы `KM_LINE` и `KM_DOSER`.

Если необходимо удалить запись в таблице, имеющей поле `DELETED`, то установить в `DELETED=1` и в дальнейшем на стороне клиента отфильтровывать подобные записи. Фактическое удаление не делать!

## Установка задачи

Для установка задачи необходимо записать в тег `TaskInstall` значение `KM_TASK.ID` нужной задачи. После записи в `TaskInstall` возвращается результат выполнения установки:

- `OK` - задача успешно установлена
- `NOT EMPTY` - тег `TaskInstall` не был очищен перед запись id задачи
- `LINK ERROR` - необходимо проверить конфигурацию, т.к. имеются не найденные модули дозаторов
- `WRONG LINE` - задача предназначена для другой линии
- `NOT FOUND` - задача с указанным id не найдена
- `TOO MANY PRODUCTS` - задача рассчитана но большее кол-во компонентов, чем указано в параметре `compQnt`

Перед записью нового id в `TaskInstall` необходимо записать пустую строку. Далее при успешной записи id задачи обнуляются все счетчики веса и циклов, а в соответствующии теги устанавливаются данные по указанной задаче.

Также в `TagInstall` можно записать `RESET` для полного сброса данных по ранее установленной задаче.

Запись id возможна только при статусе линии `IDLE`.

## Статус линии

Значени тeга `Status`:

#### 0 - IDLE

Ожидание. Если извне прописать в `Run=1` и при этом `Disable==0` и `TaskId>0` и (`CycleReq==0` или `CycleCnt<CycleReq`), то `Status=PREPARING`.

#### 1 - PREPARING

Подготовка. Если используется контрольный дозатор, то выполняется запись в `ControlDoser.SetEmptyTot=1` и ожидание `ControlDoser.IsEmptyTot==1`, после чего `Status=LOADING`.

Если контрольный дозатор не используется, то сразу `Status=LOADING`.

#### 2 - LOADING

Загрузка и взвешивание. Ожидание по всем используемым компонентам `Comp*.Status==FINISHED` (используемые компоненты - это те, у которых `WeightReq > 0`), после чего `Status=COMMITING`.

#### 3 - COMMITTING

Фиксация контрольного веса и запись весового цикла в базу данных. Если извне прописать в `Commit=1`, то выполняется запись цикла и `Status=UNLOADING`. При этом, если используется контрольный дозатор, то запись извне в `Commit=1` разрешена только при `ControlDoser.Stable=1`.

#### 4 - UNLOADING

Разгрузка. Выполняется запись `UnloadStart=1` и ожидание записи извне в `UnloadFinished=1`. Если `UnloadTimerCnt < UnloadTimerSet`, то `UnloadFinished` считается `==0`. После появления в `UnloadFinished==1` сбрасывается зафиксированный вес и `Status=IDLE`.

## Статус компонента

Значения тега `Comp0.Status`:

#### 0 - IDLE

Ожидание. Если извне прописать в `Comp0.Run=1` и при этом по все компоненты с таким же `DoserId` находятся в ожидании, и при статусе линии `Status=LOADING`, и компонент используется (`Comp0.WeightReq>0`), то `Comp0.Status=PREPARING`.

#### 1 - PREPARING

Подготовка.

- Выполнить:
  - `CompDoser.Weight=Comp0.WeightReq`
  - `CompDoser.SetEmptyCur=1`
  - `CompDoser.Run=0`
- после чего, ожидание:
  - `CompDoser.SYSTEM.ErrorFlag==0`
  - `CompDoser.IsEmptyCur==1`
  - `CompDoser.Status==0`
- если ожидание выполнено:
  - `CompDoser.Run=1`
  - `Comp0.Status=LOADING`

#### 2 - LOADING

Загрузка и взвешивание.

- Ожидание:
  - `CompDoser.SYSTEM.ErrorFlag==0`
  - `CompDoser.Finished==1`
- если ожидание выполнено, то:
  - `CompDoser.Run=0`
  - `Comp0.WeightFin=CompDoser.WeightCur`
  - `Comp0.Run=0`
  - `Comp0.Status=FINISHED`

#### 3 - FINISHED

Взвешивание выполнено. Ожидание полного завершения цикла на линии, после чего `Comp0.Status=0`.