В состав поставки входит демо-версия ScadaToolTest.epf, которая будет работать с ограничениями.
Разберем, как работает демонстрационная обработка.
Запустим внешнюю обработку, она сделана в обычных формах (рисунки 1-2).
Рисунок 1 – Открыть файл
Рисунок 2 – Выбор внешней обработки ScadaTool
При запуске обработки необходимо подключить три компоненты в определенном порядке: ScadaTools ? Python1c ? Camtool2. Порядок подключения представлен на рисунке 3.
Рисунок 3 – Порядок подключения компонент
На данный момент форма внешней обработки выглядит так:
Рисунок 4 – Форма внешней обработки
Начало работы.
Перед началом работы необходимо получить регистрационный номер, который затем нужно указать в процедурах в конфигураторе. Регистрационный номер служит для регистрации компоненты. Без указания регистрационного номера компонента будет работать в демо-режиме – ее полный функционал будет недоступен для использования.
Для получения регистрационного номера необходимо перейти на закладку «Регистрация» (рисунок 5).
Рисунок 5 – Закладка «Регистрация»
Для начала необходимо получить регистрационную строку. Для этого выполним команду «Получить регистрационную строку». Появится служебное сообщение (рисунок 6), набор символов из которого необходимо скопировать (без лишних пробелов!) и отправить на электронную почту продавца продукта.
Рисунок 6 – Пример регистрационной строки
От продавца продукта вы получите регистрационный номер, который нужно прописать в коде для дальнейшей корректной работы компоненты.
Укажем регистрационный номер в модуле формы. Для этого откроем форму Tool1с обработки (рисунок 7) и перейдем в модуль формы.
Рисунок 7 – Обработка
В процедурах кнОткрытьCOM1Нажатие, кнОткрытьCOM2Нажатие, кнЗапуститьTCPСерверНажатие, кнЗапуститьTCPКлиентНажатие и Кнопка1Нажатие вставить выданный регистрационный номер в строку РегНомер. В примерах ниже (рисунки 8-10) выделением указано место вставки регистрационного номера:
Рисунок 8 – Фрагмент процедуры кнОткрытьCOM1Нажатие (аналогично в процедуре кнОткрытьCOM2Нажатие)
Рисунок 9 – Фрагмент процедуры кнЗапуститьTCPСерверНажатие (аналогично в процедуре кнЗапуститьTCPКлиентНажатие)
Рисунок 10 – Фрагмент процедуры Кнопка1Нажатие
Регистрационный номер получен и указан в модуле формы, можно переходить к основным функциям компоненты.
Компонента ScadaTool.dll:
TCP/IP
Первая закладка «TCP/IP» предназначена для подключения протоколов TCP-клиент и TCP-сервер и обмена сообщениями сервер-клиент. Интерфейс закладки представлен на рисунке 11.
Рисунок 11 – Интерфейс закладки «TCP/IP»
- кнопка запуска/отключения сервера;
- поле ввода номера порта;
- преобразовывать сообщения в/из шестнадцатеричную систему счисления (HEX);
- статус работы сервера/клиента;
- кнопка отправки сообщения;
- поле ввода сообщения;
- кнопка запуска/отключения клиента;
- поле ввода хоста сервера;
- поле ввода сообщения;
- лог сообщений.
Чтобы приступить к работе, необходимо запустить сервер и клиент. Для запуска сервера укажем номер порта в поле ввода (2).
При необходимости преобразования установить флажок «Вывод в hex» (3) он переводит в режим «строка Hex». Режим удобен при отлаживании ответов от оборудования, в которых присутствуют неотображаемые символы.
Аналогично для клиента. Для клиента также нужно указать хост сервера в соответствующем поле (8).
Далее запустим сервер и клиент в такой последовательности: выполним команду «Запустить сервер» (1), затем выполним команду «Запустить клиент» (7). После запуска статус сервера (4) и статус клиента изменится на .
Кнопки запуска изменятся на кнопки отключения и для сервера и клиента соответственно.
При запущенном сервере и клиенте активируются ранее недоступные функции отправки сообщений. Станет доступно поле ввода сообщения от сервера клиенту (6), кнопка «Отправить сообщение» (5), а также поле ввода сообщения от клиента серверу (9) и соответствующая кнопка отправки (рисунок 12).
Рисунок 12 – Форма запущенных сервера и клиента
Все отправленные сообщения записываются в логе сообщений (10). Например, попробуем отправить сообщение от клиента серверу. Для этого в поле ввода (9) введем сообщение и выполним команду «Отправить сообщение». Ниже в логе отобразится полученное сервером сообщение (рисунок 13).
Рисунок 13 – Лог сообщений
Разберем, какие переменные объявляются при запуске сервера (аналогично для запуска клиента) в процедуре кнЗапуститьTCPСерверНажатие (рисунок 14). Данная процедура выполнятся после нажатия на кнопку «Запустить сервер» (1) (аналогично с клиентом – «Запустить клиент» (7)). Эта процедура отвечает за подключение TCP- сервера (TCP-клиента), преобразования данных в HEX и оформление или изменение элементов формы после нажатия на соответствующую кнопку.
Рисунок 14 – Процедура кнЗапуститьTCPСерверНажатие
TCPСервер.Источник – определение источника для внешнего события.
TCPСервер.Сообщение – тип событие.
TCPСервер.Timeout – время ожидания.
TCPСервер.РегНомер – регистрационный номер, выданный продавцом продукта.
TCPСервер.DataType – тип данных (1 – преобразовывать в строку HEX; 0 – не преобразовывать в HEX).
TCPСервер.MessageType – тип сообщения (-1 – целостность сообщения сохраняется, сообщение передается полностью, пока не будет достигнута контрольная сумма; 0 – сообщение передается, как есть; 0 < х – сообщение передается частями по х указанному количеству байт).
Выполнение процедуры кнОтправитьСообщениеTCPСерверНажатие (аналогично для клиента) (рисунок 15). Эта процедура отвечает за отправку сообщений по кнопке «Отправить сообщение» (5) TCP-клиентам (аналогично TCP-серверу в случае отправки сообщения от клиента) и записи отправленных сообщений или же информации об ошибках в лог сообщений (10).
Рисунок 15 – Процедура кнОтправитьСообщениеTCPСерверНажатие
TCPСервер.SendDataTCPServer – отправка сообщения всем подключенным TCP-клиентам. Если флаг «Выводить в hex» установлен, тогда произойдет преобразование строки hex в байт код.
COM
Принцип работы закладки «COM» очень схож с предыдущей закладкой. Закладка «COM» предназначена для подключения COM-портов и обмена сообщениями между портами. Интерфейс закладки представлен на рисунке 16.
Рисунок 16 – Интерфейс закладки «COM»
- кнопка открытия/закрытия первого COM-порта;
- поле ввода номера порта;
- преобразовывать сообщения в/из шестнадцатеричную систему счисления (HEX);
- статус COM-порта;
- кнопка отправки сообщения;
- поле ввода сообщения;
- кнопка открытия/закрытия второго COM-порта;
- поле ввода сообщения;
- лог сообщений.
Чтобы приступить к работе необходимо открыть COM-порты. Для запуска порта укажем его номер в поле ввода (2).
При необходимости преобразования в/из шестнадцатеричную систему счисления следует установить флажок «Вывод в hex» (3).
Аналогично для второго COM-порта.
Далее откроем оба COM-порта. Для этого выполним команду «Открыть COM порт №» (1) сначала для первого, затем для второго (7). После запуска статус каждого COM-порта (4) изменится на .
Кнопки подключения «Открыть COM порт №» изменятся на кнопки отключения .
При открытых COM-портах активируются ранее недоступные функции отправки сообщений. Станет доступно поле ввода сообщений под каждым COM-портом (6, 8) и кнопки «Отправить сообщение» (5) (рисунок 17).
Рисунок 17 – Форма запущенных COM-портов
Все отправленные сообщения записываются в логе сообщений (9). Для примера попробуем обменяться сообщениями между COM-портами. Для этого в поле ввода (6) введем сообщение и выполним команду «Отправить сообщение» (5), а затем наберем сообщение (8) и отправим его от второго COM-порта (рисунок 18). В служебных сообщениях ниже отобразится полученное каждым портом сообщение (рисунок 19).
Рисунок 18 – Отправка сообщений
Рисунок 19 – Служебные сообщения
Разберем, какие переменные объявляются при запуске СOM-порта (аналогично для COM2) в процедуре кнОткрытьCOM1Нажатие (рисунок 20). Данная процедура выполняется после нажатия на кнопку «Открыть COM порт» (1) (аналогично для второго COM-порта) и отвечает за подключение COM-порта, преобразование данных в HEX и оформление или изменение элементов формы после нажатия на соответствующую кнопку.
Рисунок 20 – Процедура кнОткрытьCOM1Нажатие
COM1.Сообщение – тип событие.
COM1.Timeout – время ожидания.
COM1.РегНомер – регистрационный номер, выданный продавцом продукта.
COM1.DataType – тип данных (1 – преобразовывать в HEX; 0 – не преобразовывать в HEX).
COM1.MessageType – тип сообщения (-1 – целостность сообщения сохраняется, сообщение передается полностью, пока не будет достигнута контрольная сумма modbus; 0 – сообщение передается, как есть; 0 < х – сообщение передается частями по х указанному количеству байт).
COM1.Источник – определение источника для внешнего события.
Выполнение процедуры кнОтправитьСообщениеCOM1Нажатие (аналогично для COM2) (рисунок 21). Эта процедура отвечает за отправку сообщений по кнопке «Отправить сообщение» (5) от одного COM-порта другому, а также записи информации о сообщениях и об ошибках в лог сообщений (9).
Рисунок 21 – Процедура кнОтправитьСообщениеCOM1Нажатие
COM1.SendDataCOM – отправка сообщения подключенным COM-портам. Если флаг «Выводить в hex» установлен, тогда произойдет преобразование строки hex в байт код.
Счетчики
Закладка «Счетчики» предназначена для тестирования сообщений modbus, но для работы потребуется подключение к реальному оборудованию или эмулятору.
Здесь же реализован пример изменения картинки с выводом полученных данных.
Интерфейс закладки представлен на рисунке 22.
Рисунок 22 – Интерфейс закладки «Счетчики»
- картинка;
- картинка;
- рандом;
- поле ввода адреса устройства в сети modbus;
- код команды чтения;
- адрес регистра;
- количество байт, которые требуется считать;
- кнопка запуска/остановки.
Для работы с счетчиками должна быть заполнена и подключена одна из компонент на предыдущих вкладках – TCP/IP или COM в зависимости от того, какой транспортный протокол будем использовать для обмена по modbus.
В поле ввода (4) необходимо ввести адрес устройства в сети modbus. Затем в поле ввода (5) вести код команды. Ниже представлены коды команд:
-
01 (0x01) Чтение DO Read Coil Status Дискретное Чтение
-
02 (0x02) Чтение DI Read Input Status Дискретное Чтение
-
03 (0x03) Чтение AO Read Holding Registers 16 битное Чтение
-
04 (0x04) Чтение AI Read Input Registers 16 битное Чтение
В поле (6) ввести адрес регистра, с которого начать чтение и ввести в поле ввода (7) количеств байт, которое необходимо считать.
Например, для расходомера Visit (рисунок 23):
Рисунок 23 – Пример для расходомера ВЗЛЕТ ТЭР
Мы видим, что начиная с физического адреса 0х8020(32800) по 0х8022(32802) хранится целая часть расхода. Начиная с физического адреса 0х8022(32800) по 0х8024(32802) дробная. Наша задача прочитать и преобразовать эти данные в читаемое число.
Мы вводим адрес устройства в сети modbus у нас это 1, адрес начального регистра 32800 и считываем 4 ячейки (2 целое число и 2 дробную часть).
После ввода всех необходимых данных выполним команду «Старт» (8). После запуска кнопка изменится на «Стоп». Запустится опрос устройства.
Рисунок 24 – Процедура кнСчетчикиСтартСтопНажатие
Рисунок 25 – Процедура ОбработкаСчетчиков
Для опроса используем для отправки функции: GetMDataCOM – если транспорт COM порт; GetMDataTCPCl если транспорт TCPКлиент будут отправлять запросы по modbus.
Ответ получаем во внешнем событии.
Пример:
TCPКлиент.GetMDataTCPCl – ЗапросМТСПКл (Id устройства, номер команды, адрес регистра, количество регистров,0); отправить modbus сообщение.
При работе с modbus рекомендуется установить флаг MessageType в -1. DataType в 1 (строка HEX).
В нашем примере используем подключение TCPКлиент, который подключается к преобразователю Moxa NPORT 5150 в режиме TCPServer (192.168.1.99 порт 503), к которому подключен расходомер Взлет по протоколу rs485.
Рисунок 26 – Подключение TCPКлиента
Заполнены адрес 1, команда чтения 4, физический адрес ячейки 32800 и количество ячеек 4 (рисунок 27).
Рисунок 27 – Заполнение закладки «Счетчики» и получение ответа
Получаем ответ: 0007453 3F61A195 (во внешнем событии).
Каждая ячейка состоит из пары байт. Левые 4 – это наша целая часть, правые 4 – наша дробная часть. В компоненте для режима «строка Hex» предусмотрены функции преобразования: HexToInt для целых чисел и HexToReal для дробных.
Счетчик1.CreateImage(ДанныеКартинки1); // Запоминаем неизмененную картинку как шаблон;
x1=Число(TCPКлиент.HexToInt((Лев(Данные,8)))); // получаем целое число
Число(TCPКлиент.HexToReal(Прав(Данные,8))); // получаем дробное число
Счетчик1.TextOut(9999,"Arial",7,15,30,0,Лев(Строка(x1),10)); // выводим на картинку текст
ФайлКартинки1=Base64Значение(Счетчик1.Ellipse(0,800*ПоказанияСчетчика1,10,10,30,30)); // выводим круг, получаем картинку с текстом и нарисованным кругом в углу в формате base64 и сразу преобразовываем
ЭлементыФормы.КартинкаСчетчик1.Картинка = Новый Картинка(ФайлКартинки1); // отрисовываем на форме
|
Некоторые устройства могут передавать ответ, переворачивая последовательность битов (справа налево), слов (меняются местами старший и младший бит) или все вместе, в этом случае ответ сравниваем с показанием прибора и строковыми операциями расставляем правильно.
При работе с картинкой помните про особенности 1С, связанные с кэшированием и очисткой памяти, описанные в начале. Ниже, в примере «Видеосканер», показан тот самый «костыль», который позволил нам работать с картинкой – это не очень красиво, но пока другого выхода не нашли.
Компонента camtool2.dll:
Видео сканер
Закладка «Видео сканер» предназначена для проверки подключения видеокамеры, получения картинки с камеры. Также функционал позволяет распознавать и считывать штрихкоды.
На рисунке 28 представлен интерфейс закладки.
Рисунок 28 – Интерфейс закладки «Видео сканер»
- поле HTML-документа;
- поле картинки с камеры;
- кнопка подключения камеры;
- кнопка создания мгновенного снимка;
- кнопка очистки видео.
Перед началом работы необходимо подключить камеру к компьютеру. Когда камера подключена и работает ее нужно запустить в нашей компоненте. Для этого выполним команду «Подключить» (3).
Изображение с камеры появится в поле (2).
Для создания мгновенного снимка с камеры необходимо выполнить команду «Снапшот» (4). Изображение появится в поле (3).
Для отключения от потока камеры нужно выполнить команду «Очистить видео» (5).
Рассмотрим процедуры, которые выполняются на этой закладке (рисунки 29-31).
Процедура Кнопка1Нажатие (рисунок 29) выполняется при нажатии на кнопку «Подключить» (3) на форме. Данная процедура отвечает за подключение камеры, вывод видео на форму и распознавание штрихкодов.
Рисунок 29 – Процедура Кнопка1Нажатие
Камера.Источник – определение источника для внешнего события.
Камер.РегНомер – регистрационный номер, выданный продавцом продукта.
Камера.Сообщение – тип событие.
Камера.ВидеоВПотоке – значение 0 не передает поток в реальном времени в 1С; значение 1 выведет свою форму (не 1С) с изображением; значение 2 картинка в base64 формате будет передаваться внешним событием.
Камера.ДатаМатриксВПотоке – распознавание кодов из библиотеки Datamatrix (dtmxlib). Это тестовая функции, качество работы зависит от качества картинки и позиции камеры. Требуется библиотека libdmtx.dll.
Камера.БарКодВПотоке – распознавание кодов из библиотеки Zxing, также тестовая функция.
Камера.ПутьКБиблиотеке – путь библиотеке, где лежит файл ANCamMod.dll. Она нужна нам для подключения к камере. Этот же путь используется для поиска libdmtx.dll
Камера.ПодключитьВидеоПоток – запуск видео.
Следующая процедура Кнопка2Нажатие (рисунок 30) выполняется при нажатии кнопки «Снапшот» (4) и отвечает за создание мгновенного снимка (даже если Камера.ВидеоВПотоке = 0) и помещения его картинкой на форму (2).
Если раскомментировать строку
//ЭлементыФормы.П.УстановитьТекст("<img src=""data:image/gif;base64,"+Данные+ """ />"); |
картинка пойдет в поле HTML.
Рисунок 30 – Процедура Кнопка2Нажатие
Процедура Кнопка3Нажатие (рисунок 31) выполняется при нажатии кнопки «Очистить видео» (5) и отвечает за очищение картинки с видеокамеры.
Рисунок 31 – Процедура Кнопка3Нажатие
Баркод
Следующая закладка «Баркод» предназначена для генерации штрихкодов.
Интерфейс закладки представлен на рисунке 32.
Рисунок 32 – Интерфейс закладки «Баркод»
- текстовое поле;
- кнопка генерации картинки;
- кнопка генерации кода;
- поле картинки (изображение);
На рисунке 33 представлен пример генерации баркода.
Рисунок 33 – Пример работы закладки
Рассмотрим процедуры, которые выполняются на этой закладке (рисунки 34-35).
Процедура Кнопка11Нажатие (рисунок 34) выполняется при нажатии на кнопку «Кнопка1». Эта процедура отвечает за генерацию штрихкода.
Рисунок 34 – Процедура Кнопка11Нажатие
Параметры:
-
Путь zint – строка – указываем путь к компоненте zint.dll;
-
Тип кода – строка – выбираем нужный тип штрихкода;
-
Цвет штрихкода black – целочисленное;
-
Цвет фона white 16777215 – целочисленное;
-
upDown Borderwidth если включено обводка – целочисленное;
-
Белое поле вокруг – бул;
-
Высота – целочисленное;
-
DotSize – дробное число;
-
Масштаб = 1 – дробное число;
-
Угол наклона 0 – целочисленное;
-
Показывать текст или нет – бул;
-
[opSmallText] – бул;
-
[opBoldText] – бул;
-
[opBars] – бул;
-
[opBox] – бул;
-
[opDotty] – бул;
-
Текст Кода – строка;
-
PrimaryMessage – строка.
При нажатии на кнопку «Кнопка2» происходит выполнение процедуры Кнопка22Нажатие (рисунок 35). Данная процедура предназначена для вывода списка всех доступных видов штрихкодов.
Рисунок 35 – Процедура Кнопка22Нажатие
В параметре указан путь к zint.dll.
Компонента python1c.dll:
Питон
Ниже приведены несколько примеров использования возможностей Python в 1С на закладке «Питон» (рисунок 36).
Рисунок 36 – Интерфейс закладки «Питон»
Вы можете использовать установленный предварительно движок питон на рабочей станции или сервере в зависимости от задачи.
Убедитесь, что вы установили сам Python и библиотеки, которые собираетесь использовать. Разрядность Python должна соответствовать разрядности 1С и компоненты!При установке Python следует поставить галочку добавить в переменные Path!
Инициализация — кнопка «Создать Питон»:
Питон = Новый("AddIn.TpythonB.TpythonB"); – Инициализируем переменную;
Питон.Источник = "Питон"; – Указываем источник для внешних событий от компоненты;
Питон.Сообщение = "Сообщение"; – Тип стандартного сообщения для внешних событий;
Питон.AnswerType=1; – 1 – транслировать консоль (print(“ххх”)) во внешнее событие; 0 – не транслировать;
Питон.РегНомер = 224753070; – Регистрационный номер, полученный при регистрации.
Питон.СоздатьПитон(); – Начинаем инициализацию;
Питон.НоваяПеременная("FilePath"); – Объявляем переменные, если собираемся использовать. Описано во втором примере. Это не обязательно!
Питон.НоваяПеременная("Pic");
Питон.Init(); – Заканчиваем инициализацию;
|
После нажатия кнопки вы можете проверить работу, набрав команду: print(2+2). Затем нажать кнопку «Запустить скрипт». Если Питон.AnswerType=1 при инициализации, то вы увидите сообщение «4» (рисунок 37). Это значит, что все настроено правильно.
Если Питон.AnswerType=0, то ответ вы получите в результате функции: результат = Питон.ВыполнитьСкрипт(ПитонСкрипт).
Рисунок 37 – Проверка работы
Кнопка «Запустить скрипт» выполняет функцию Питон.ВыполнитьСкрипт(ПитонСкрипт).
Примеры прикладных задач
Пример 1 – Раскрой.
Одна из прикладных задач – это оптимизация раскроя или укладки одномерного, двумерного или объемного материала. В основе этого примера лежит библиотека с открытым исходным кодом Google OR-Tools. Эта библиотека содержит множество алгоритмов оптимизации кроя, маршрутов и т.д., и является одной из самых производительных. Пример использования при помощи питон взят отсюда: GitHub – emadehsan/csp, внесены минимальные изменения для удобства использования в 1С (код read_lengths.py перенесен в основной модуль). В данном примере мы напрямую вносим данные из полей ввода в скрипт питона перед исполнением.
1. Если ранее не нажимали, нажимаем кнопку «Создать питон».
2. Заполняем строку отрезков и длину исходного материала.
Строка отрезков (это то, что хотим оптимизировать) задается в виде пар целочисленных значений [количество, длинна]. Например, [1,120],[2,240],[4,210].
Размер исходного материала задаем целочисленным значением – размер отреза исходного материала. Например, 1000 (рисунок 38).
Рисунок 38 – Оптимизация раскроя
Нажимаем кнопку «1. Раскрой». Заполнится поле «Код питон» с учетом ваших значений. Нажимаем «Запустить скрипт». Получаем вариант раскроя наших кусочков на отрезках исходного материала.
В коде реализовано два варианта оптимизации. Переключиться на второй можно, установив галочку «Оптимальный». После снова выполнить команды «Раскрой» и «Запустить скрипт». Увидим другой вариант раскроя.
Пример 2 – Распознавание номера автомобиля по фото, источник Notebooks.
Нужно установить в python библиотеки opencv, numpy, mathlib, pytesseract (выполнив из командной строки pip install название_библиотеки).
Xml c предобученным каскадом, там же много других можно взять здесь: https://github.com/spmallick/mallick_cascades.
Подменяя каскады, можно искать на картинке разные объекты. В нашем примере мы ищем номер автомобиля.
Нам потребуется установленное приложение tesseract, которое можно скачать здесь https://github.com/UB-Mannheim/tesseract/wiki. Уже на найденном кусочке фото с номером с помощью этой программы и библиотеки pytesseract для нее мы распознаем символы (рисунок 39).
Рисунок 39 – Распознавание номера автомобиля по фото
Так же, как и в первом случае, сначала выполняем команду «Создать питон». Далее «2. Номер машины». Заполнится скрипт. Отличие этого варианта в том, что мы передаем данные через переменные (после выполнения кода, если нужно, можно так же получить последние значения переменных).
Передаем значения через строковый параметр, поэтому бинарные данные мы передаем через base64.
Вы получите несколько вариантов распознавания в зависимости от настроек tesseract. В вашем случае вы можете остановится на наиболее подходящей настройке для вашего случаю. Подробнее о работе tesseract можно прочитать на сайте утилиты.