doc:jroboplc:modules:arctrm_dev

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
doc:jroboplc:modules:arctrm_dev [2026/07/23 07:47] denisdoc:jroboplc:modules:arctrm_dev [2026/08/01 18:06] (current) denis
Line 3: Line 3:
 ===== 1. Назначение ===== ===== 1. Назначение =====
  
-''ArctrmModule'' - модуль архивации температурных значений. Он читает значения датчиков из тегов уже настроенных модулей оборудования, сохраняет периодические срезы в базу Firebird и пишет события изменения состояния связи с устройствами.+''ArctrmModule'' - модуль архивации температурных значений. Он читает значения датчиков из тегов уже настроенных модулей оборудования, сохраняет периодические срезы в базу Firebird и пишет события изменения состояния связи с устройствами и потери актуальности данных подвесов.
  
-Сам модуль не реализует протокол обмена с оборудованием. Доступ к данным выполняется через ''Ref'': каждый ''Sensor'' ссылается на тег вида ''<deviceName>:Pdv<num>.T<sensorIndex>'', а ''ArctrmDevice'' контролирует состояние устройства через ''<deviceName>:SYSTEM.ErrorFlag''. По коду видно, что конфигурация устройств берется из секции ''promauto.termo5''; тип ''promauto.termo5'' создается периферийным плагином как ''PaTermo5Module''.+Сам модуль не реализует протокол обмена с оборудованием. Доступ к данным выполняется через ''Ref'': каждый ''Sensor'' ссылается на тег вида ''<deviceName>:Pdv<num>.T<sensorIndex>'', ''Podves'' проверяет актуальность данных по ''<deviceName>:Pdv<num>.Time'', а ''ArctrmDevice'' контролирует состояние устройства через ''<deviceName>:SYSTEM.ErrorFlag''. По коду видно, что конфигурация устройств берется из секции ''promauto.termo5''; тип ''promauto.termo5'' создается периферийным плагином как ''PaTermo5Module''.
  
 Описание плагина в ''ArctrmPlugin.getPluginDescription()'' - ''termo value archiver''. Описание плагина в ''ArctrmPlugin.getPluginDescription()'' - ''termo value archiver''.
Line 18: Line 18:
 | ''ArctrmDataService'' | Инкапсулирует работу с БД: поиск модуля базы, проверку Firebird, загрузку и выполнение скрипта, синхронизацию ''PODVES'', запись ''TEMPER'' и ''EVENTLOG'', удаление старых архивных строк и учет текущего размера архива. | | ''ArctrmDataService'' | Инкапсулирует работу с БД: поиск модуля базы, проверку Firebird, загрузку и выполнение скрипта, синхронизацию ''PODVES'', запись ''TEMPER'' и ''EVENTLOG'', удаление старых архивных строк и учет текущего размера архива. |
 | ''ArctrmDevice'' | Описывает одно настроенное устройство, содержит список ''Podves'', читает ''SYSTEM.ErrorFlag'' и пишет события изменения статуса устройства. | | ''ArctrmDevice'' | Описывает одно настроенное устройство, содержит список ''Podves'', читает ''SYSTEM.ErrorFlag'' и пишет события изменения статуса устройства. |
-| ''Podves'' | Описывает один подвес устройства, содержит список ''Sensor'', синхронизирует запись в ''PODVES'', сохраняет одну строку архива со всеми своими датчиками. |+| ''Podves'' | Описывает один подвес устройства, проверяет актуальность данных по тегу ''Pdv<num>.Time'', содержит список ''Sensor'', синхронизирует запись в ''PODVES'', сохраняет строку архива с актуальными данными и формирует событие потери актуальности. |
 | ''Sensor'' | Ссылается на температурный тег, читает целочисленное значение и заменяет отсутствующие или выходящие за диапазон значения специальными кодами. | | ''Sensor'' | Ссылается на температурный тег, читает целочисленное значение и заменяет отсутствующие или выходящие за диапазон значения специальными кодами. |
 | ''Duration'' | Разбирает строковый период и выравнивает дату-время на границу периода. | | ''Duration'' | Разбирает строковый период и выравнивает дату-время на границу периода. |
-| ''Constants'' | Содержит коды событий и специальные значения датчиков. |+| ''Constants'' | Содержит коды событийспециальные значения датчиков и предел актуальности данных подвеса. |
 | ''Defaults'' | Содержит значения конфигурации по умолчанию. | | ''Defaults'' | Содержит значения конфигурации по умолчанию. |
-| ''ArctrmException'' | Проверяемое исключение для ошибок подготовки и инициализации Arctrm. |+| ''Params'' | Пустой класс; в текущей реализации не используется. | 
 +| ''ArctrmException'' | Проверяемое исключение для ошибок конфигурации, подготовки и инициализации Arctrm. |
  
 Прямое подключение к базе выполняет только ''ArctrmDataService''. Остальная часть модуля работает с объектами предметной модели и теговыми ссылками. Прямое подключение к базе выполняет только ''ArctrmDataService''. Остальная часть модуля работает с объектами предметной модели и теговыми ссылками.
Line 46: Line 47:
   * состояние ''lastStatus'', по которому определяется необходимость записи события.   * состояние ''lastStatus'', по которому определяется необходимость записи события.
  
-''Podves'' создается по записи внутри конфигурации устройства. Номер подвеса получается из ключа конфигурации через ''entry.getKey().substring(1)'' и ''Integer.parseInt(...)''. Например, ключ ''p3'' дает номер ''3''. Имя подвеса формируется как ''<deviceName>.<podvesNum>'', а значение конфигурации сохраняется как описание ''descr''.+''Podves'' создается по записи внутри конфигурации устройства. Номер подвеса получается из ключа конфигурации через ''entry.getKey().substring(1)'' и ''Integer.parseInt(...)''. Например, ключ ''p3'' дает номер ''3''. Имя подвеса формируется как ''<deviceName>.<podvesNum>'', а значение конфигурации сохраняется как описание ''descr''. Кроме списка датчиков подвес создает ссылку ''refTime'' на тег ''<deviceName>:Pdv<num>.Time'' и хранит признаки ''dataValid'' и ''needSaveEvent''.
  
 ''Sensor'' создается для каждого индекса от ''0'' до ''sensorCount - 1''. Имя тега строится так: ''Sensor'' создается для каждого индекса от ''0'' до ''sensorCount - 1''. Имя тега строится так:
Line 84: Line 85:
   - Генерирует SQL вставки в ''TEMPER'' с колонками ''T0..T<n-1>''.   - Генерирует SQL вставки в ''TEMPER'' с колонками ''T0..T<n-1>''.
  
-После подготовки сервиса модуль вызывает ''prepare()'' у каждого устройства. Устройства подготавливают ссылки на ''SYSTEM.ErrorFlag'', а подвесы - ссылки всех датчиков.+После подготовки сервиса модуль вызывает ''prepare()'' у каждого устройства. Устройства подготавливают ссылки на ''SYSTEM.ErrorFlag'', а подвесы - ссылки всех датчиков и ''Pdv<num>.Time''.
  
 В конце подготовки выставляется ''needInit = true'', а ''lastDt'' сбрасывается в ''null''. В конце подготовки выставляется ''needInit = true'', а ''lastDt'' сбрасывается в ''null''.
Line 113: Line 114:
   - Берется серверное время базы через ''svc.now()''.   - Берется серверное время базы через ''svc.now()''.
   - Время округляется вниз до границы периода через ''Duration.floorToPeriod(...)''.   - Время округляется вниз до границы периода через ''Duration.floorToPeriod(...)''.
-  - Все устройстваподвесы и датчики обновляют текущие значения.+  - Все устройства и подвесы обновляют состояние; датчики опрашиваются только у подвесов с актуальным значением ''Pdv<num>.Time''.
   - Если рассчитанный ''dt'' отличается от ''lastDt'', сохраняется архивный срез и выполняется очистка старых строк.   - Если рассчитанный ''dt'' отличается от ''lastDt'', сохраняется архивный срез и выполняется очистка старых строк.
   - Для каждого устройства проверяется состояние связи и при изменении пишется событие в ''EVENTLOG''.   - Для каждого устройства проверяется состояние связи и при изменении пишется событие в ''EVENTLOG''.
Line 121: Line 122:
 ==== Сохранение данных ==== ==== Сохранение данных ====
  
-При наступлении нового периода каждое устройство вызывает ''savePodves(...)'', каждый подвес собирает значения своих датчиков и передает их в ''svc.saveTemper(dt, id, values)''. В базу пишется одна строка ''TEMPER'' на один подвес.+При наступлении нового периода каждое устройство вызывает ''savePodves(...)''. Подвес с актуальными данными собирает значения своих датчиков и передает их в ''svc.saveTemper(dt, id, values)''; в базу пишется одна строка ''TEMPER''. Если ссылка на ''Pdv<num>.Time'' не найдена или значение находится вне диапазона ''0..600'', строка для этого подвеса не создается.
  
-События состояния устройства сохраняются отдельно через ''svc.saveEvent(...)''. Событие пишется только при изменении статуса относительно ''lastStatus''.+События состояния устройства сохраняются отдельно через ''svc.saveEvent(...)''. Событие пишется только при изменении статуса относительно ''lastStatus''. Событие ''EVENT_PODVES_UPDATE_STALE'' формируется при первой потере актуальности данных подвеса и сохраняется вызовом ''Podves.save(...)'' при наступлении следующего архивного периода.
  
 ==== Останов и reload ==== ==== Останов и reload ====
Line 137: Line 138:
 ==== Таблица ''EVENTLOG'' ==== ==== Таблица ''EVENTLOG'' ====
  
-Назначение: хранение событий модуля и событий изменения состояния устройств.+Назначение: хранение событий модуляизменения состояния устройств и потери актуальности данных подвесов.
  
 <code sql> <code sql>
Line 152: Line 153:
 | ''DT'' | Время события; при записи берется ''db.getServerDatetime()''. | | ''DT'' | Время события; при записи берется ''db.getServerDatetime()''. |
 | ''EVENT_CODE'' | Код события из ''Constants''. | | ''EVENT_CODE'' | Код события из ''Constants''. |
-| ''MESSAGE'' | Сообщение; для статуса устройства используется имя устройства. |+| ''MESSAGE'' | Сообщение; для статуса устройства используется имя устройства, для потери актуальности - имя подвеса, для инициализации - пустая строка. |
  
 Индекс: ''IX_EVENTLOG_DT'' по полю ''DT''. Индекс: ''IX_EVENTLOG_DT'' по полю ''DT''.
Line 159: Line 160:
  
 ^ Константа ^ Значение ^ Где используется ^ ^ Константа ^ Значение ^ Где используется ^
-| ''EVENT_ARCTRM_INIT'' | ''0'' | Записывается при инициализации Arctrm. | +| ''EVENT_ARCTRM_INIT'' | ''100'' | Записывается при инициализации Arctrm. | 
-| ''EVENT_CONNECTED'' | ''1'' | Записывается при переходе устройства в состояние связи. | +| ''EVENT_DEVICE_CONNECTED'' | ''99'' | Записывается при переходе устройства в состояние связи. | 
-| ''EVENT_DISCONNECTED'' | ''2'' | Записывается, если ''SYSTEM.ErrorFlag == true''. | +| ''EVENT_DEVICE_DISCONNECTED'' | ''1'' | Записывается, если ''SYSTEM.ErrorFlag == true''. | 
-| ''EVENT_NOLINK'' | ''3'' | Записывается, если ссылка на ''SYSTEM.ErrorFlag'' не найдена. |+| ''EVENT_DEVICE_NOLINK'' | ''0'' | Записывается, если ссылка на ''SYSTEM.ErrorFlag'' не найдена и предыдущий статус имел другой код. | 
 +| ''EVENT_PODVES_UPDATE_STALE'' | ''3'' | Записывается при первой потере актуальности данных подвеса; в ''MESSAGE'' передается имя ''<deviceName>.<podvesNum>''. |
  
 Очистка ''EVENTLOG'' в коде не реализована. Очистка ''EVENTLOG'' в коде не реализована.
Line 232: Line 234:
   -> ArctrmDevice.update()   -> ArctrmDevice.update()
      -> Podves.update()      -> Podves.update()
-        -> Sensor.update()+        -> Podves.checkTimeValid() 
 +        -> Sensor.update() при актуальных данных
 </code> </code>
  
-''Sensor.update()'' работает только с теговой ссылкой:+Сначала ''Podves.update()'' проверяет ссылку ''Pdv<num>.Time''. Данные считаются актуальными, если ссылка существует, а значение тега находится в диапазоне от ''0'' до ''PODVES_UPDATE_TIME_LIMIT = 600'' включительно. При неактуальных данных ''Sensor.update()'' не вызывается и значения датчиков остаются прежними. 
 + 
 +Для подвеса с актуальными данными ''Sensor.update()'' работает с теговой ссылкой:
  
 ^ Условие ^ Записываемое значение ^ ^ Условие ^ Записываемое значение ^
-| Тег не найден через ''ref.linkIfNotValid()'' | ''VALUE_NOLINK = 3000''+| Тег не найден через ''ref.linkIfNotValid()'' | ''VALUE_NOLINK = 3013''
-| Значение меньше ''-1000'' | ''VALUE_BROKEN = 3010''+| Значение меньше ''-1000'' | ''VALUE_SHORTAGE = 3010''
-| Значение больше ''2000'' | ''VALUE_SHORTAGE = 3011'' |+| Значение больше ''2000'' | ''VALUE_BROKEN = 3011'' |
 | Значение в диапазоне | Исходное целое значение тега | | Значение в диапазоне | Исходное целое значение тега |
  
Line 275: Line 280:
 Архивные строки пишутся только если рассчитанный ''dt'' отличается от ''lastDt''. При записи: Архивные строки пишутся только если рассчитанный ''dt'' отличается от ''lastDt''. При записи:
  
-  * каждое устройство сохраняет все свои подвесы+  * каждое устройство вызывает ''save(...)'' для всех своих подвесов
-  * каждый подвес формирует список текущих значений датчиков; +  * каждый подвес с актуальными данными формирует список текущих значений датчиков; 
-  * ''ArctrmDataService.saveTemper(...)'' вставляет одну строку ''TEMPER''.+  * ''ArctrmDataService.saveTemper(...)'' вставляет одну строку ''TEMPER'' для каждого подвеса с актуальными данными; 
 +  * подвес с неактуальными данными не создает строку ''TEMPER'', но при установленном ''needSaveEvent'' записывает событие ''EVENT_PODVES_UPDATE_STALE''.
  
 Формат подготовленного SQL строится один раз при подготовке: Формат подготовленного SQL строится один раз при подготовке:
Line 345: Line 351:
 В этом примере ''plugin.arctrm'' и ''module.arctrm'' соответствуют схеме загрузки конфигурации: ''ConfigurationYaml.getModuleConf(...)'' ищет ''plugin.<pluginName>'' и внутри него ''module.<moduleName>''. Значения ''database'', ''period'', ''size'', ''schema'' и ''sensorCount'' читаются в ''ArctrmModule.loadModule()''. В этом примере ''plugin.arctrm'' и ''module.arctrm'' соответствуют схеме загрузки конфигурации: ''ConfigurationYaml.getModuleConf(...)'' ищет ''plugin.<pluginName>'' и внутри него ''module.<moduleName>''. Значения ''database'', ''period'', ''size'', ''schema'' и ''sensorCount'' читаются в ''ArctrmModule.loadModule()''.
  
-Секция ''promauto.termo5'' передается в ''ArctrmDevice.load(...)''. Ключи ''mytrm1'' и ''mytrm2'' становятся именами модулей-источников тегов. Ключи ''p0'', ''p5'' и ''p1'' дают номера подвесов ''0'', ''5'' и ''1'', потому что код берет часть ключа после первого символа и разбирает ее как число. При ''sensorCount: 6'' для каждого подвеса создаются ссылки на теги ''Pdv<num>.T0'' ... ''Pdv<num>.T5''.+Секция ''promauto.termo5'' передается в ''ArctrmDevice.load(...)''. Ключи ''mytrm1'' и ''mytrm2'' становятся именами модулей-источников тегов. Ключи ''p0'', ''p5'' и ''p1'' дают номера подвесов ''0'', ''5'' и ''1'', потому что код берет часть ключа после первого символа и разбирает ее как число. При ''sensorCount: 6'' для каждого подвеса создаются ссылки на теги ''Pdv<num>.T0'' ... ''Pdv<num>.T5'', а также ссылка на ''Pdv<num>.Time''.
  
 Комментарий ''#604800'' в строке ''size'' является YAML-комментарием и не участвует в значении параметра. Активное значение в примере - ''30''. Комментарий ''#604800'' в строке ''size'' является YAML-комментарием и не участвует в значении параметра. Активное значение в примере - ''30''.
Line 401: Line 407:
  
 ^ Условие ^ Код события ^ ^ Условие ^ Код события ^
-| Ссылка на ''SYSTEM.ErrorFlag'' не найдена | ''EVENT_NOLINK''+| Ссылка на ''SYSTEM.ErrorFlag'' не найдена | ''EVENT_DEVICE_NOLINK = 0''
-| Ссылка есть, ''ErrorFlag == true'' | ''EVENT_DISCONNECTED''+| Ссылка есть, ''ErrorFlag == true'' | ''EVENT_DEVICE_DISCONNECTED = 1''
-| Ссылка есть, ''ErrorFlag == false'' | ''EVENT_CONNECTED'' |+| Ссылка есть, ''ErrorFlag == false'' | ''EVENT_DEVICE_CONNECTED = 99'' | 
 + 
 +Событие пишется только при изменении состояния относительно ''lastStatus''. Поле ''lastStatus'' изначально равно ''0'', поэтому начальное состояние ''EVENT_DEVICE_NOLINK'' не записывается, а начальные состояния ''EVENT_DEVICE_DISCONNECTED'' и ''EVENT_DEVICE_CONNECTED'' записываются. Низкоуровневые ошибки обмена с оборудованием Arctrm не анализирует; они видны только через теги внешних модулей. 
 + 
 +==== Неактуальные данные подвеса ==== 
 + 
 +Ссылка на ''Pdv<num>.Time'' считается неактуальной, если она не найдена либо содержит значение меньше ''0'' или больше ''600''. При переходе ''dataValid'' из ''null'' или ''true'' в ''false'' устанавливается ''needSaveEvent''. До восстановления актуальности датчики не опрашиваются, а строка ''TEMPER'' для подвеса не записывается.
  
-Событие пишется только при изменении состояния относительно ''lastStatus''Низкоуровневые ошибки обмена с оборудованием Arctrm не анализирует; они видны только через теги внешних модулей.+При наступлении следующего архивного периода ''Podves.save(...)'' записывает ''EVENT_PODVES_UPDATE_STALE = 3'' с именем подвеса в ''MESSAGE'' и сбрасывает ''needSaveEvent''Повторное событие возможно только после восстановления актуальности и ее новой потери; отдельное событие восстановления не предусмотрено.
  
 ==== Некорректные значения датчиков ==== ==== Некорректные значения датчиков ====
  
-Значения ниже ''-1000'' заменяются на ''VALUE_BROKEN'', значения выше ''2000'' - на ''VALUE_SHORTAGE''. Отдельные события и отдельное логирование для таких значений не реализованы.+Значения ниже ''-1000'' заменяются на ''VALUE_SHORTAGE = 3010'', значения выше ''2000'' - на ''VALUE_BROKEN = 3011''. Отдельные события и отдельное логирование для таких значений не реализованы.
  
-Если тег датчика не найден, значение становится ''VALUE_NOLINK''. Такие датчики дополнительно подсчитываются в ''getInfo()''.+Если тег датчика не найден, значение становится ''VALUE_NOLINK = 3013''. Такие датчики дополнительно подсчитываются в ''getInfo()''.
  
 ==== Неожиданные исключения ==== ==== Неожиданные исключения ====
Line 435: Line 447:
 | Однократная загрузка списка колонок ''TEMPER'' при init | Позволяет добавить только отсутствующие ''T*''-колонки. | | Однократная загрузка списка колонок ''TEMPER'' при init | Позволяет добавить только отсутствующие ''T*''-колонки. |
  
-JDBC batch-вставки не используются: при наступлении периода выполняется одна вставка на каждый подвес.+JDBC batch-вставки не используются: при наступлении периода выполняется одна вставка на каждый подвес с актуальными данными.
  
 ===== 11. Ограничения ===== ===== 11. Ограничения =====
Line 477: Line 489:
   * ''ArctrmPlugin.java'';   * ''ArctrmPlugin.java'';
   * ''ArctrmException.java'';   * ''ArctrmException.java'';
-  * ''Context.java'';+  * ''Params.java'';
   * ''src/main/resources/dbscr/dbscr.arctrm.yml'';   * ''src/main/resources/dbscr/dbscr.arctrm.yml'';
   * ''DatabaseProtoServiceImpl.java'';   * ''DatabaseProtoServiceImpl.java'';
Line 489: Line 501:
   * Пример конфигурации предоставлен как документационный; штатный Arctrm-конфиг в просмотренных файлах репозитория не найден.   * Пример конфигурации предоставлен как документационный; штатный Arctrm-конфиг в просмотренных файлах репозитория не найден.
   * Бизнес-смысл событий известен только по именам констант.   * Бизнес-смысл событий известен только по именам констант.
-  * Низкоуровневое поведение оборудования находится вне Arctrm; модуль видит только теги и ''SYSTEM.ErrorFlag''.+  * Низкоуровневое поведение оборудования находится вне Arctrm; модуль видит только теги датчиков, ''Pdv<num>.Time'' и ''SYSTEM.ErrorFlag''.
   * Требования к эксплуатационной очистке ''EVENTLOG'', удалению старых ''PODVES'' и реакции на внешние изменения базы в коде не определены.   * Требования к эксплуатационной очистке ''EVENTLOG'', удалению старых ''PODVES'' и реакции на внешние изменения базы в коде не определены.
  • doc/jroboplc/modules/arctrm_dev.1784782076.txt.gz
  • Last modified: 2026/07/23 07:47
  • by denis