Наконец закончил мажорную версию реализации протокола ModBus на Ruby - rmodbus. Решил написать о нововведениях и подытожить свою работу.
Что нового в 1.0.0?
Новое API
Я уже писал небольшое описание проекта и основные возможности, все это относится к версии 0.5.0. В новом релизе было переработано API клиентской части библиотеки. Очень важный недостаток предыдущей версии был в том, что для каждого ведомого необходимо было создавать свое соединение, что приводило к необходимости к открытию\закрытию TCP сокета или COM порта для обращения к другому ведомому. В примере происходит копирования значений 10 регистров из 1-го ведомого во 2-й.:
32-х разрядные данные
Теперь библиотека поддерживает 32-х разрядные регистры и регистры с плавающей точкой. Сама поддержка осуществятся через вспомогательные методы:
Поддержка JRuby
Теперь можно библиотеку использовать и на JRuby, но без ModBus RTU реализации, так как для работы с последовательным портом нужен гем serialpoort. Я собрал гем для Java, удалив эту зависимость и классы RTU реализации.
Зачем нужен ModBus на Ruby?
О сильных и слабых сторонах Ruby я думаю уже известно, иначе до этой строки Вы не дочитали бы :) Естественно такая реализация не претендует на решение для встроенных систем или для систем с критичным подходом к производительности. Навряд ли Вы захотите ее как то использовать для написании своего OPC сервера или интеграции ее в SCADA. Но эта библиотека может пригодиться для быстрого подключение к модбас устройству, ведь необходимо всего несколько строк. Можно написать скрипты для тестирования взаимодействия ПЛК с верхним уровнем и т.д. RModBus используется для интеграции ПЛК с веб приложениями (Rails, Senatra, Ramaze) к тому же можно писать веб сервисы используя протоколы RESTFull, SOAP, RPC-XML и т.д. В этом ключе.
Что бы повысить интерес к таким легким решениям как rmodbus, привожу пример чтения данных по ModBus на Java (jamod):
Заключение
Я веду этот проект с 2008 года. Версия 0.1.0 поддерживала только TCP клиента и работала на Ruby-1.8.6. Теперь это вполне стабильная библиотека с поддержкой как клиентской, так и серверной части. Поддерживает RTU, RTU по TCP и TCP реализации модбас. Работает на всех популярных реализациях Ruby. Я затеял проект больше для обучения Ruby, чем для практического применения, но в итоге есть и реальные внедрения. Было много писем и патчей от разработчиков по всему миру, я не только учился программировать, но и изъяснятся на английском, работать в команде) Ниже перечислены люди которые внесли весомый вклад в проект:
Kelley Reynolds - реализация RTUViaTCP, идея нового API для версии 1.0.0, реализация вспомогательных методов для работы с 32-х разрядными данными и методы [] чтения\записи данных ведомого;
Hector G. Parra -реаниматор проекта serialpoort, благодаря ему стала возможна реализация RTU ModBus;
jsanders - первый патч:);
Tallak Tveide - идея обращения к устройству внутри блока;
Mark Flocco - тесты с реальными ПЛК.
Идей о будущем функционале у меня нет. По этому проект развивается по мере появления запросов на новые функции и сообщения об ошибках. Так что если есть какие то идеи и замечания, то сюда и на английском.
Что нового в 1.0.0?
Новое API
Я уже писал небольшое описание проекта и основные возможности, все это относится к версии 0.5.0. В новом релизе было переработано API клиентской части библиотеки. Очень важный недостаток предыдущей версии был в том, что для каждого ведомого необходимо было создавать свое соединение, что приводило к необходимости к открытию\закрытию TCP сокета или COM порта для обращения к другому ведомому. В примере происходит копирования значений 10 регистров из 1-го ведомого во 2-й.:
regs = [] ModBus::TCPClient.connect('127.0.0.1', 502, 1) do |cl| regs = cl.read_holding_registers(0,10) end ModBus::TCPClient.connect('127.0.0.1', 502, 2) do |cl| cl.write_multiple_registers(0,regs) endТеперь можно обращаться к ведомым внутри одного соединения:
# Подключаемся к TCP ModBus серверу IP 127.0.0.1, порт 502 ModBus::TCPClient.connect('127.0.0.1', 502) do |cl| # Обращение к ведому по адресу 1 cl.with_slave(1) do |slave| # Чтение значений 10 регистров начиная с адреса 0 regs = slave.read_holding_registers(0,10) end
# Обращение к ведому по адресу 2 cl.with_slave(2) do |slave| # Запись 10 значений начиная с адреса 0 slave.write_multiple_registers(0,regs) end endЧтение\запись через функции немного громоздкое и требует помнить их названия, по этому можно использовать другой способ:
ModBus::TCPClient.new('127.0.0.1', 8502) do |cl| cl.with_slave(1) do |slave| # Чтение одного регистра по адресу 16 slave.holding_registers[16] # Запись одного регистра по адресу 16 slave.holding_registers[16] = 123 # Чтение регистров с адреса 16 по 20 slave.holding_registers[16..20] # Запись регистров с адреса 16 по 20 slave.holding_registers[16..20] = [1, 2, 3, 4, 5] end endТаким образом можно обратиться к 4-м областям памяти ведомого (согласно спецификации ModBus): coils, discrete_inputs, holding_registers и input_registers.
32-х разрядные данные
Теперь библиотека поддерживает 32-х разрядные регистры и регистры с плавающей точкой. Сама поддержка осуществятся через вспомогательные методы:
# Чтение 32-х разрядного регистра res = slave.holding_registers[0..1] res.inspect => [20342, 17344] res.to_32i => [1136676726] res.to_32f => [384.620788574219] # Запись 32-х разрядного регистра cl.holding_registers[0..1] = [1136676726].from_32i cl.holding_registers[0..1] => [20342, 17344] cl.holding_registers[2..3] = [384.620788574219].from_32f cl.holding_registers[2..3] => [20342, 17344]
Поддержка JRuby
Теперь можно библиотеку использовать и на JRuby, но без ModBus RTU реализации, так как для работы с последовательным портом нужен гем serialpoort. Я собрал гем для Java, удалив эту зависимость и классы RTU реализации.
Зачем нужен ModBus на Ruby?
О сильных и слабых сторонах Ruby я думаю уже известно, иначе до этой строки Вы не дочитали бы :) Естественно такая реализация не претендует на решение для встроенных систем или для систем с критичным подходом к производительности. Навряд ли Вы захотите ее как то использовать для написании своего OPC сервера или интеграции ее в SCADA. Но эта библиотека может пригодиться для быстрого подключение к модбас устройству, ведь необходимо всего несколько строк. Можно написать скрипты для тестирования взаимодействия ПЛК с верхним уровнем и т.д. RModBus используется для интеграции ПЛК с веб приложениями (Rails, Senatra, Ramaze) к тому же можно писать веб сервисы используя протоколы RESTFull, SOAP, RPC-XML и т.д. В этом ключе.
Что бы повысить интерес к таким легким решениям как rmodbus, привожу пример чтения данных по ModBus на Java (jamod):
//Соединение InetAddress addr = InetAddress.getByName('127.0.0.1'); TCPMasterConnection con = new TCPMasterConnection(addr); con.setPort(502); con.connect(); //Подготовка запроса ReadInputDiscretesRequest req = new ReadInputDiscretesRequest(0, 10); //Подготовка транзакции ModbusTCPTransaction trans = new ModbusTCPTransaction(con); trans.setRequest(req); // Чтение trans.execute(); ReadInputDiscretesResponse res = (ReadInputDiscretesResponse) trans.getResponse(); System.out.println("Digital Inputs Status=" + res.getDiscretes().toString())Против:
ModBus::TCPClient.connect('127.0.0.1', 502) do |cl| cl.with_slave(1) do |slave| puts "Digital Inputs Status=" + slave.discrete_inputs[0..10].to_s end endМожно еще короче
puts "Digital Inputs Status=%s" % ModBus::TCPClient.connect('127.0.0.1', 502).with_slave(1).holding_registers[0.10]
Заключение
Я веду этот проект с 2008 года. Версия 0.1.0 поддерживала только TCP клиента и работала на Ruby-1.8.6. Теперь это вполне стабильная библиотека с поддержкой как клиентской, так и серверной части. Поддерживает RTU, RTU по TCP и TCP реализации модбас. Работает на всех популярных реализациях Ruby. Я затеял проект больше для обучения Ruby, чем для практического применения, но в итоге есть и реальные внедрения. Было много писем и патчей от разработчиков по всему миру, я не только учился программировать, но и изъяснятся на английском, работать в команде) Ниже перечислены люди которые внесли весомый вклад в проект:
Kelley Reynolds - реализация RTUViaTCP, идея нового API для версии 1.0.0, реализация вспомогательных методов для работы с 32-х разрядными данными и методы [] чтения\записи данных ведомого;
Hector G. Parra -реаниматор проекта serialpoort, благодаря ему стала возможна реализация RTU ModBus;
jsanders - первый патч:);
Tallak Tveide - идея обращения к устройству внутри блока;
Mark Flocco - тесты с реальными ПЛК.
Идей о будущем функционале у меня нет. По этому проект развивается по мере появления запросов на новые функции и сообщения об ошибках. Так что если есть какие то идеи и замечания, то сюда и на английском.
Комментариев нет:
Отправить комментарий