Pull to refresh

Comments 6

Проблема не в потоках, а в попытке выполнять IO задачу синхронно. Посмотрите в сторону какой нибудь библиотеки для реализации цикла событий, например libuv, чтобы было реализовано получение уведомления о данных на канале связи с устройством.

Так же вам стоит реализовать объединение запросов чтения: вместо чтения каждого регистра по одному - объединяйте их чтение в один большой запрос диапазона регистров, а потом уже разбирайте полученный диапазон по своим DataPoint

Чем то похожим я занимаюсь здесь:
https://github.com/cyanidle/radapter/blob/56a79ae0b76f1bc991a914cd7606f86e5135405b/src/workers/modbus/modbus_units.hpp#L121

Спасибо, мысль отличная. Чтение диапазонами выглядит намного логичнее. Нужна чёткая карта регистров и корректно разбирать полученный блок по диапозонам. Буду думать, как это аккуратно встроить в текущую архитектуру. Кстати, тут как раз был опыт поиска данных в памяти прибора ТЭМ104 🙂


Приветствую.
Сначала выбрать модель получения данных push - инициатива отправителя передать данные, или pull - сервер (ваше приложение) само опрашивает все контроллеры и прочее.
Выбрать надо только одну модель, обе не стоит брать (по-крайней мере сразу).
Я бы выбрал push модель.
А для тех контроллеров, которые ждут чтобы к ним обращались за данными, сделал бы отдельные прокси-программы, которые занимаются их опросом. И здеь важно, что не классы внутри сервера, а именно отдельные исполняемые модули, можно их на скриптовом языке написать для удобства, у них задачка не большая - обращаться к контроллеру периодич-ки и на сервер пересылать.

Дальше, прием данных на сервере. Предлагаю делать через промежуточный циклический буфер, размер расчитывать по времени и объема, пусть на 10 мин, например.
Соотвественно, контроллеры присылают данные в разных потоках пусть, пишут каждый в свою позицию в буфере.
В другом потоке вы идете по тому же буферу и данные дальше как-то используете - показывайте на экране, сохр в БД и прочее.

вот пример буфера вам
https://github.com/Tyill/SVisual/blob/master/src/SVServer/src/buffer_data.cpp

Спасибо за развёрнутый комментарий. Подход интересный - по сути, это уже отдельный слой сбора и доставки данных перед самой SCADA. Вполне возможно, что в будущем по такой схеме можно будет выделить отдельные модули.

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

Отсутствие связи определяется по таймауту? Здесь тоже нужно не повешать обмен пытаясь 50 регистров опросить и в каждом дождаться таймаута.

я для себя также писал телеграмм бота с опросом чего угодно по ОРС. Сделал на DA, сейчас допиливаю UA и в планах еще без орс протоколы s7 и модбас тср допилить.

У меня получилось в итоге что каждый орс клиент это отдельный поток. В основном потоке у меня диспетчер тэгов. В тэги из своих потоков пишутся текущие значения, коды качества. А потребители данных через этот же диспетчер запрашиваю значения или присылают значения для записи.

Кстати модет быть тоже посмотреть в сторону ОРС. OPC UA очень удобная технология и поддерживается много чем. Низкоуровневый обмен уже решен на орс сервере или на уровне библиотеки орс ua.

Спасибо за обратную связь. Да, идея с группировкой регистров и более аккуратной работой с таймаутами разумна, особенно с тамймаутам, можно просто положить систему на них. Подход с общим диспетчером тэгов тоже понятен. В сторону OPC UA я тоже смотрю - это уже де-факто современный стандарт, но для текущего этапа пока хочу сначала довести Modbus/MQTT runtime логику.

Sign up to leave a comment.

Articles