Узел ModbusTCP ============== **Modbus TCP** — это протокол связи, используемый для передачи данных между устройствами в промышленных сетях. Протокол является частью стандарта Modbus, который был разработан для обеспечения простого и эффективного способа связи между электронными устройствами. **Modbus TCP** (Modbus over TCP/IP) использует протокол TCP/IP для передачи данных по сетям Ethernet. Этот протокол работает на прикладном уровне модели OSI. Передает данные в формате TCP/IP пакетов, которые включают в себя заголовок Modbus и полезную нагрузку. Данный протокол подходит для больших расстояний и большого количества устройств, так как Ethernet позволяет легко масштабировать сеть. .. figure:: ../../_img/input-modbustcp.png :alt: ModbusTCP module ModbusTCP module Узел опроса устройств по протоколу Modbus TCP. Конфигурация узла: ------------------ |ModbusTCP module| Входные данные ~~~~~~~~~~~~~~ **Структура:** - **ip** - адрес устройства, к которому мы подключаемся - **port** - порт через который происходит связь с устройством ``int`` - **device-name** - наименование устройства (произвольно) ``str`` - **period** - время опроса подключенных устройств в *мс* ``int`` - **order** - ``ByteOrder`` - *big* - BigEndian (BE). Cамый старший байт имеет наименьший адрес. ``str`` - *любое другое значение* - LittleEndian (LE). Порядок от младшего к старшему. ``str`` - **scale** - масштаб значения. 1 - отсутствие масштабирования. ``double`` - **function** - тип запрашиваемой операции. Доступно 4 варианта: ``str при настройке, но в регистр идёт int`` - *FC01* - Coil Status - *FC02* - Input Status - *FC03* - Holding Register - *FC04* Input Register - **type** - тип передаваемых данных, можно написать CapsLock-ом. ``str`` - *float64*, *float32* *uint32*, *uint16* -*int32*, *int16* - *bool* - **quantity** - Количество регистров для чтения. ``int`` - **1**- для **type** = *int16, uint16, bool* - **2** - для **type** = *int32, uint32, float32* - **4** - для **type** = *float64* - **address** - адрес регистра с которого начинается чтение. ``int`` - **property-name** - имя свойства для идентификации данных. ``str`` - **source** - Источник данных ``str`` - **device-id** - идентификатор устройства ``int`` - Вкладка **Ручные**: в разработке… - Вкладка **Из файла**: Загрузка настроек из файла **.csv**. Пример содержимое **.csv** файла с настройками: .. csv-table:: Устройства и их параметры :header: "ip", "port", "device-name", "period", "order", "scale", "function", "type", "quantity", "address", "property-name", "source", "device-id" :widths: 15, 5, 10, 6, 5, 5, 10, 5, 5, 5, 12, 10, 5 "192.168.1.194", "1502", "umg", "5000", "big", "1", "FC03", "int16", "1", "0", "address0", "ABC/adr0", "1" "192.168.1.194", "1502", "umg", "5000", "big", "1", "FC03", "int16", "1", "1", "address1", "ABC/adr1", "1" "192.168.1.194", "1502", "umg", "5000", "big", "1", "FC03", "int16", "1", "2", "address2", "ABC/adr2", "1" **Csv** :: ip;port;device-name;period;order;scale;function;type;quantity;address;property-name;source;device-id 192.168.1.194;1502;umg;5000;big;1;FC03;bool;1;0;address0;ABC/adr0;1 192.168.1.194;1502;umg;5000;big;1;FC03;bool;1;1;address1;ABC/adr1;1 192.168.1.194;1502;umg;5000;big;1;FC03;bool;1;2;address2;ABC/adr2;1 Выходные данные ~~~~~~~~~~~~~~~ * **connection_status**: bool * **device**: string * **time**: uint64 * **timer**: std::chrono::duration_cast * **values[]**: * **address**: int * **property-name**: string * **source**: string * **type**: string * **value**: string **Json** :: { "connection_status": Ok, "device": "umg", "time": 1672531200000, "timer": 1, "values": [ { "address": 0, "property-name": "address0", "source": "ABC/adr0", "type": "int16", "value": "0" }, { "address": 1, "property-name":"address1", "source": "ABC/adr1", "type": "int16", "value": 1 }, { "address": 2, "property-name":"address2", "source": "ABC/adr2", "type": "int16", "value": 2 } ] } .. raw:: html
Пример создания цепочки с загрузкой конфигурации Modbus устройства из файла: ---------------------------------------------------------------------------- Пример будет приведен на локальном устройстве с использованием эмулятора ModbusSlave. Если вы не пользователь Windows, то **Wine** - отличное решение. 1. Добавим в ваш **compose.yaml** следующий сервис: .. code:: yaml modbus_tcp: container_name: modbusTCP_emul restart: on-failure build: dockerfile: ./test_server/mbs_eml_tcp.Dockerfile ports: - 1502:1502 .. Надеюсь, файл mbs_eml_tcp.Dockerfile будет у вас для теста. 2. Узнаем ip нашего хоста в сети: |image1| 3. Создаём файл **.csv** для входных данных в узел **ModbusTCP** (пример смотрим в описании), ставим в столбец **ip** ваш адрес > Обязательно должны быть все ячейки адресы быть одинаковыми! 4. Добавьте узел **ModbusTCP**, выберите вкладку **File**, загрузите файл в виде, как указано выше, в формате **CSV**: 5. Добавьте узел **Вывод в сокет**, соедините узлы: |image2| 6. Запустим наш *compose.yaml*, должно собраться всё успешно. 7. Запустите ModbusSlave, во вкладке *connection* добавьте новое подключение, как на изображении (чтобы поменять значение ip: снимите флажок с *Any Address*, при сохранении верните флажок в исходное состояние), можно оставить значение как 127.0.0.1 или |image3| 8. Сохраните собранную цепочку в PromUC и откройте консоль браузера для удостоверения в том, что узел ModbusTCP работает - должна загореться зеленая лампочка. |image4| 9. Откроем ModbusSlave и в *Communication Traffic* можем наблюдать: |image5| У меня закончился пробный период modbus slave, поэтому я скачал diagslave (/Документы). Чтобы его запустить следует ввести: .. code:: bash sudo ./diagslave -p 21502 .. |ModbusTCP module| image:: ../../_img/input-modbustcp-settings.png .. |image1| image:: ../../_img/modbus_ip_find.png .. |image2| image:: ../../_img/modbus_input_chain.png .. |image3| image:: ../../_img/modbus_input_conSetup.png .. |image4| image:: ../../_img/modbus_input_socket.png .. |image5| image:: ../../_img/modbus_input_comTraffic.png