# wessvr

Модуль архивации весовых данных. Предназначен для замены старого архиватора (wessvr.exe). Данный модуль требует включения в задачу.

Поддерживает работу со следующими модулями:

Название в wesclient | Название в БД | Периферийный модуль
--- | --- | ---
Standard | standard | wessvr.adapter
Gelios | gelios | promauto.gelios.flow
Gelios.Maslo2v2 | gelios.maslo2v2 | promauto.gelios.maslo2v2

Рекоммендуется во всех случаях использовать универсальный модуль wessvr.adapter.

В системе может быть более одного одновременно работающих модулей wessvr с разными svrnamе. Один модуль может содержать несколько устройств. Устройства - это весы и прочи ее оборудование, данные которых подлежат архивации. Список устройств и их конфигурация содержится в базе данных (таблица `MODULES`).

Как и в старом wessvr значения счетчиков накапливаются в оперативных таблицах `MAIN` и `MAINHR`, после чего сбрасываются в архивы STAT и STATHR по одному из событий:

- наступление нового периода (смена или час)
- изменение в таблице MODULES одного из значений IDPROD, IDBRIG или IDBATCH.
- откат счетчиков

## Основные отличия от старого wessvr

- Уменьшено количество транзакций на цикл. Выборочно устанавливается режим одна транзакция на цикл, либо подтверждение после обработки каждого устройство (параметр `singleTransaction`).
- Отображение отката счетчиков в архивах `STAT` и `STATHR` отдельной записью и пометкой в поле `SETBACK`. Пример ситуации:

      Диапазон счетчика веса = 1000.
      Значение SWEND откатывается с 950 на 50.
      Расчет веса при откате: 100 = 1000 - 950 + 50.

      |  SWBEG|  SWEND|    WES|SETBACK|
      +-------+-------+-------+-------+
      |    750|    950|    200|      0|
      |    950|     50|    100|      1|
      |     50|    450|    400|      0|

  Реальный пример:

- Настраиваемые таблицы архивирования. Помимо стандартных MAIN/STAT и MAINHR/STATHR можно сделать архивацию через любое количество минут.
- В `MAIN`ы добавлено поле `PERIOD`.
- Возможность отключать передачу значения в WesSvrState устройства.
- Автоматическое создание базы данных при ее отсутствии.

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

    plugin.wessvr:
      enable: on

      module.wessvr:
        svrname:    wessvr
        database:   db
        schema:     zlak
        singleTransaction: on
        wesSvrStateEnabled: on

        arctables:
          - main:     MAIN
            stat:     STAT
            interval: 0

          - main:     MAINHR
            stat:     STATHR
            interval: 60

          - main:     MAIN5M
            stat:     STAT5M
            interval: 5

## Параметры

Параметр | Умолчание | Описание
--- | --- | ---
svrname | `` | Имя сервера архивации для определения «своих» устройств в базе данных
database | `db` | Модуль базы данных (database)
schema | `` | Имя схемы (для firebird это префикс имен метаданных). Оставить пустым при обычном переходе со старого wessvr
singleTransaction | `on` | Одна транзакция на цикл `on` или подтверждение после каждого устройства `off`
wesSvrStateEnabled | `on` | Разрешение записи в теги WesSvrState устройств
tagsources | `` | Deprecated! Определения модулей источников тегов полностью автоматизировано. Список модулей, предоставляющих теги устройств. Требуется в случае, если архивируемое устройство не находится непосредственно в системе, а импортируется посредством другого модуля, например, rpclient
arctables | `` | Список параметров таблиц архивирования. По умолчанию настроены стандартные для старого wessvr пары MAIN/STAT и MAINHR/STATHR. Если данных параметр используется, то умолчание перекрывается новой конфиграцией
arctables
main | `` | Имя оперативной таблицы
stat | `` | Имя архивной таблицы
interval | `0` | Интервал архивирования. Возможные значения: 0 - смена от 0 до <60 - минуты от 60 до <1440 - часы 1440 - сутки

## arctables по умолчанию

Если `arctables` не указать явно, то будет использована следующая конфигурация:

        arctables:
          - main:     MAIN
            stat:     STAT
            interval: 0

          - main:     MAINHR
            stat:     STATHR
            interval: 60

## Теги

Имя тега | Описание
--- | ---
Connected | Состояние работы модуля. Нормальное значение `on`, иначе архивация не выполняется из-за отсутствия подключения к базе данных или ошибки при инициализации (подробности смотреть в log-файлах)

Для каждого устройства создается набор тегов. Теги начинаются с имени устройства (для примера далее используется имя устройства WFST):

Имя тега | Описание
--- | ---
WFST.state | Cостояние архивации: 0 - OK 1 - нет связи 2 - ошибка целостности (CRC16) 3 - данные не достоверны 4 - нет данных (теги не найдены) 99 - старт архивации
Далее для каждого вида архива, определенном в `arctables` (пример для `MAIN`)
WFST.MAIN.period | Значение поля `PERIOD`
WFST.MAIN.pertype | Значение поля `PERTYPE`
WFST.MAIN.wes | Значение `WES` за текущий период. Данные суммируются из двух таблиц `MAIN` и `STAT`.
WFST.MAIN.wnum | Значение `WNUM` за текущий период. Данные суммируются из двух таблиц `MAIN` и `STAT`.

## Расчет текущей производительности

Существует два способа получения текущей производительности, определяемые в `MODULES.OUTCALCMODE`, равное 0 по умолчанию.

При значении 0 текущая производительность считывается из тега Output. При значении > 0 текущая производительность расcчитывается на основе поступающих данных текущего веса.

Полученная производительность, записываемая в `ARCVAL.SUMWES`, является средним значением за период `MODULES.ARCOUTTIME` (секунды). Периодичность записи в `ARCVAL` установливается в `MODULES.ARCOUTPER` (секунды).

## Запись статуса

Как и везде, в таблице `ARCSTATUS` для обратной совместимости оставлены старые названия полей. Назначение полей следующее:

- NOCONNECT - связь с модулем:
  - 0 - ОК
  - >0 - отсутствует
- NOOPC - не используется
- NODATA - статус архивации
  - 0 - OK
  - 1 - нет связи
  - 2 - ошибка целостности (CRC16)
  - 3 - данные не достоверны
  - 4 - нет данных (теги не найдены)
  - 99 - старт архивации
  - 100 - архивация отключена

## Отключение записи статуса

Иногда значения полей `STATUS1..5` изменяются сильно часто, что делает архивацию статуса малоинформативной. Например, ранние версии весового блока Гелиос в State отображали не только текущий режим, но и стадию дозирования. Для предотвращения подобной ситуации в таблице `MODULES` есть поле `ARCSTATUS_OFF`, по умолчанию равное 0. Если требуется не реагировать на изменение какого-либо поля `STATUS1..5` необходимо взвести соответствующий бит этого поля.

Например, при значении 1, изменение STATUS1 не повлечет добавление новой записи в таблицу `ARCSTATUS`. При значении 0x1F все изменения в `STATUS1..5` игнорируются.

## Запись простоев

Простоем модуля называется временной интервал между двумя последовательно выполненными отвесами, значение которого превышает заданное предельное время (порог простоя).

Для фиксации простоев модуля предназначена таблица `STATIDLE`.

Порог простоя задается в `MODULES.TIMEIDLE` отдельно по каждому модулю. Если задан 0, то фиксация простоев не выполняется.

Принцип работы
1. При старте считывается время последнего отвеса из `ARCVAL.DT`.
2. Ожидание фиксации нового отвеса в `ARCVAL`.
2. После фиксации отвеса в ARCVAL вычисляется интервал между временами последнего и текущего отвесов
3. Если полученное значение превышает порог простоя, то создается запись в `STATIDLE`
4. Время текущего отвеса запоминается как время последнего отвеса.
5. Переход к п.2.

## Предотвращение "миллионов"

Для предотвращения «миллионов» (больших значений в `MAIN`/`STAT`) используются две проверки `StepBack` и `BigDeltaWes`.

`StepBack` - защита от отката назад. Если значение счетчика веса или отвесов изменилось и стало меньше чем предыдущие, то выдерживается пауза 60 секунд.

`BigDeltaWes` - защита от слишком большого увеличения значения веса. Если значение счетчика веса увеличилось на более чем допустимое, то выдерживается время 60 секунд. Допустимое значение задается в поле `MODULES.WESINCMAX` командой:

    m:wmax <idm> <value>

Для удобства определения `WESINCMAX` можно использовать команду `m:wmaxlist`:

    run>wessvr:wmaxlist

    run>
     IDM DESCR                 WESINCMAX    LASTWES   DELTAWES
       1:WHIGH                    250000      49953      49620
       2:WFST                     250000      29982      29900
       3:WSCN                     250000      20002      20040
       4:WVHZ                     250000      52436      51477
       5:WOTR                     250000      25329      25170
      12:WEL1                     250000       8312       9200
      13:WEL2                     250000       8996      10005
      14:WBKKA                    250000      29852      29740
      15:WSHZA                    250000      15062      14990
      16:WSHMA                    250000      24994      25000
      17:WSHBA                    250000      50123      44950
      20:WBFAS                    250000          0       2002
      22:WBKAR                    250000      10125      20200
      23:WELV                    5000000     911000     898000
      24:WSHBB                    250000          0      45420
    OK

    run>wessvr:wmax 12 50000

    run>OK

В выводе команды `m:wmaxlis` две правые колонки подсказывают, какое должно быть значение в `WESINCMAX`, и обозначают следующее:

- `LASTWES` - среднее значение поля `LASTWES` последних 10 записей в таблице `ARCVAL`
- `DELTAWES` - наименьшая разница между значениями поля `SUMWES` последних 10 записей в таблице `ARCVAL`

Рекомендуется устанавливать значение `WESINCMAX` раз в 5-10 большим, чем значение заданной дозы весов.

Если значение `WESINCMAX` не установлено (равен 0 или null), то оно рассчитывается во время работы автоматически (последнее изменение веса, умноженное на 5).

## Переходный импорт данных

Для перехода со старого архиватора wessvr.exe на новый требуется перенести данные из старой базы данных в новую, создаваемою автоматически модулем `wessvr`. Описание действий по шагам:

- создать два модуля `database` для подключения к новой (не существующей) и старой (существующей) базам данных.

      plugin.database:
        module.db:
          type:        firebird
          dbname:      /database/wes_fb30.fdb
          properties:
            encoding: WIN1251

        module.dbold:
          type:        firebird
          dbname:      /database/old_wes_fb30.fdb
          properties:
            encoding: WIN1251

      plugin.wessvr:
        module.wessvr:
          database:  db

      plugin.task:
        module.taskmain:
          modules:
            - db
            - wessvr

- запустить систему и выполнить команды:

      wessvr:import dbold
      reload wessvr

Данный способ перехода является рекомендуемым, т.к. новая база будет избавлена от ненужных артефактов, накопленных годами. Также в новой базе оптимизированы индексы некоторых таблиц.

Другой способ перехода - использовать старую базу. При этом потребуется добавить поле `PERIOD` типа `integer` в таблицы `MAIN` и `MAINHR`.

## Удаление старых STAT-записей

В архивных таблицах `STAT` и `STATHR` данные сохраняются без циклической перезаписи, и таким образом постоянно накапливаются. Для удаления ненужных данных используется команда `w:sweep <year>`. Пример использования:

    wessvr:sweep 2016

Данная команда, посылаемая модулю с именем `wessvr`, удаляет все записи старше 2016 года включительно.

## Хранимые процедуры

### FETCH_STAT

Для удобства построения отчетов в старом варианте весовой базы данных имеются хранимые процедуры `GET_STAT` и `GET_STATHR`. Они имеются и в новой версии базы данных, создаваемой автоматически модулем `wessvr`. Однако теперь вместо них рекомендуется использовать более эффективную универсальную процедуру FETCH_STAT:

    CREATE PROCEDURE FETCH_STAT (
            TBLNAME VARCHAR(64),
            PERBEG INTEGER,
            PEREND INTEGER,
            MNAME0 VARCHAR(16), ... MNAME9 VARCHAR(16),
            ANDTEXT VARCHAR(200) = '')
        RETURNS (
            PERIOD INTEGER,
            WES0 BIGINT, ... WES9 BIGINT)

На входе необходимо указать имя таблицы (`STAT`, `STATHR` и т.д), период выборки включительно и имена устройств. Например, почасовая выборка за месяц:

    SELECT * FROM FETCH_STAT('STATHR', 2017110100, 2017113123,
          'WHIGH', 'WFST', 'WSCN', 'WOTR', 'WFDR', '', '', '', '', '')

В параметре `ANDTEXT` можно задать дополнительное условие выборки, например:

    SELECT * FROM FETCH_STAT('STATHR', 2017110100, 2017113123,
          'WHIGH', 'WFST', 'WSCN', 'WOTR', 'WFDR', '', '', '', '', '', 'and idprod=7')

### FETCH_MAIN

Данная процедура служит для удобства отображения текущих данных из таблицы MAIN. Проблема в том, что данные за текущую смену могут частично уже находится в STAT, например, из-за смены продукта, обнуления счетчика и т.д. Процедура `FETCH_MAIN` позволяет отобразить суммарные текущие данные простым запросом. Сигнатура процедуры:

    CREATE PROCEDURE FETCH_MAIN (
            TBLMAIN VARCHAR(64),
            TBLSTAT VARCHAR(64),
            WHERETEXT VARCHAR(200))
        RETURNS (
            IDM INTEGER,
            NAME VARCHAR(16),
            DESCR VARCHAR(32),
            DTBEG TIMESTAMP,
            PERIOD BIGINT,
            WES BIGINT,
            WNUM BIGINT)

Пример использования:

    SELECT * FROM FETCH_MAIN('MAINHR','STATHR',
          'where md.name=''WHIGH'' or md.name=''WFST'' order by md.descr')

В `WHEREHTEXT` можно указать любое дополнительное условие `WHERE`, а также задать сортировку `ORDER BY`, используя алиасы таблиц:

- MD. - `MODULES`
- M. - `MAIN`
- S. - `STAT`

### FETCH_STAT_SUM

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

    CREATE PROCEDURE FETCH_STAT_SUM (
        TBLNAME VARCHAR(64),
        PERBEG INTEGER,
        PEREND INTEGER,
        WNAME0 VARCHAR(16) = '', ... WNAME9 VARCHAR(16) = '',
        ANDTEXT VARCHAR(200) = '')
    RETURNS (
        DESCR0 VARCHAR(32), ... DESCR9 VARCHAR(32),
        DTBEG0 TIMESTAMP,   ... DTBEG9 TIMESTAMP,
        DTEND0 TIMESTAMP,   ... DTEND9 TIMESTAMP,
        WES0 BIGINT,        ... WES9 BIGINT,
        WNUM0 BIGINT,       ... WNUM9 BIGINT)

### FETCH_MAIN_SUM

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

    CREATE PROCEDURE FETCH_MAIN_SUM (
        TBLMAIN VARCHAR(64),
        TBLSTAT VARCHAR(64),
        WNAME0 VARCHAR(16) = '', ... WNAME9 VARCHAR(16) = '',
        WHERETEXT VARCHAR(200) = '')
    RETURNS (
        DESCR0 VARCHAR(32), ... DESCR9 VARCHAR(32),
        DTBEG0 TIMESTAMP,   ... DTBEG9 TIMESTAMP,
        WES0 BIGINT,        ... WES9 BIGINT,
        WNUM0 BIGINT,       ... WNUM9 BIGINT)

### FETCH_ARCVAL_LAST

Процедура предназначена для построения отчетов о текущей производительности:

    CREATE PROCEDURE FETCH_STAT_SUM (
        WNAME0 VARCHAR(16) = '', ... WNAME9 VARCHAR(16) = '')
    RETURNS (
        DESCR0 VARCHAR(32),       ... DESCR9 VARCHAR(32),
        DT0 TIMESTAMP,            ... DT9 TIMESTAMP,
        OUTWES0 DOUBLE PRECISION, ... OUTWES9 DOUBLE PRECISION)