Стартовая страница › Форумы › Понять, как работает ПО › Из MQTT в ModBusTCP
- В этой теме 22 ответа, 3 участника, последнее обновление 1 месяц, 1 неделя назад сделано
IvanovVladimir.
-
АвторСообщения
-
06.05.2026 в 12:53 #43218
IvanovVladimir
Участник(Минимально) У меня есть 2 канала, один modbus tcp (101), второй MQTT (102). Оба канала настроены как входной\выходной. При отправке команды с брокера MQTT в скаду я меняю значение канала 102. Я хотел, чтобы без МАУ у меня значение из 102 канала при получении команды передавалось в канал 101 и отправлялась команда в ПЛК к привязанному регистру. Алгоритм прост, при получении команды на 102 канал, я сравниваю полученное значение из MQTT сообщения с значением 101 канала и если они различны записываю в 101 канал новое значение от имени пользователя, чтобы команда в ПЛК тоже полетела (без пользователя просто меняется значение на сервере но команда не отправляется на ПЛК). Столкнулся с еще одной проблемой и не понимаю как решить, вот алгоритм:
1) отправляю mqtt на 102 канал со значением 0
2) канал 101 становится 0 и отправляет команду на плк
3) через мнемосхему отправляю переключателем команду на изменение значения канала 101 в 1
4) команда отправляется и в плк
5) отправляю команду 0 в канал 102 по MQTT
6) значение канала 101 и соответственно команда к плк происходит только через минуту
Описание: Если в канале 102 значение одинаковое с тем которое я отправляю по MQTT то значение копируется в 101 и отправляется на плк только через минуту, если в канале 102 значение отличается от того что я отправляю по MQTT то значение в 101 меняется сразу как и отправка команды на ПЛК.Я написал модуль в котором настраиваю из каких каналов в какие должно копироваться значение. Подскажите как мне исправить ошибку с отложенной отправкой команды на ПЛК?
Код модуля логики (функция обработки):
public override void OnCurrentDataProcessed(Slice slice)
{
if (slice?.CnlNums == null || moduleConfig.Mappings.Count == 0)
return;foreach (int changedCnlNum in slice.CnlNums)
{
foreach (var mapping in moduleConfig.Mappings)
{
if (changedCnlNum == mapping.SourceCnl)
{
// Получаем актуальное значение исходного канала (только что обновлённое)
CnlData sourceData = ServerContext.GetCurrentData(mapping.SourceCnl);
if (!sourceData.IsDefined)
continue;double newVal = sourceData.Val;
// Получаем текущее значение целевого канала
CnlData targetData = ServerContext.GetCurrentData(mapping.TargetCnl);// Если целевой канал не определён или его значение отличается от пришедшего
if (!targetData.IsDefined || Math.Abs(targetData.Val — newVal) > double.Epsilon)
{
TeleCommand cmd = new TeleCommand(mapping.TargetCnl, newVal, moduleConfig.UserID);
ServerContext.SendCommand(cmd);if (moduleConfig.VerboseLog)
Log.WriteInfo($»[{Code}] Канал {mapping.SourceCnl}→{mapping.TargetCnl}, значение={newVal}»);
else
Log.WriteAction($»[{Code}] Команда отправлена в канал {mapping.TargetCnl}»);
}
else
{
if (moduleConfig.VerboseLog)
Log.WriteInfo($»[{Code}] Значение в целевом канале {mapping.TargetCnl} уже равно {newVal}, пропуск.»);
}
}
}
}
}-
Тема изменена 1 месяц, 1 неделя назад пользователем
Mikhail.
06.05.2026 в 16:06 #43230IvanovVladimir
УчастникМожет там нужно как то статус менять канала или привязываться к событию…? Чтобы отработала команда сразу а не при следующем чтении архива сервером в течение минуты
-
Ответ изменён 1 месяц, 1 неделя назад пользователем
IvanovVladimir.
06.05.2026 в 16:15 #43233
manjey73УчастникВы уверены что команда отложенная? а не то, что вы видите ее изменение после режима «Чтение после команды» ?
06.05.2026 в 16:17 #43234
manjey73УчастникЕсли у вас длительный опрос, то команда выставляется в очередь, когда опрос заканчивается, отсылается команда, потом идет чтение после команды и только тогда вы видите изменение.
06.05.2026 в 16:25 #43237IvanovVladimir
УчастникЯ уверен что команда отложенная так как ПЛК рядом со мной физически и я смотрю значения непосредственно как в администраторе так и в веб интерфейсе. Еще если действовать по тому алгоритму то в логах будет четко видно, что:
12:00:00 — получена команда по mqtt
12:00:39 — отправлена команда на плк
12:00:43 — получена команда по mqtt
12:01:39 — отправлена команда на плк
12:01:23 — получена команда по mqtt
12:02:39 — отправлена команда на плкто есть команда на плк отправляется после команды mqtt, но только ровно в конкретное время с интервалом в минуту, это не то чтобы задержка, это изменение применилось, но сервер его обработал только по минутному таймеру
06.05.2026 в 16:33 #43238IvanovVladimir
Участник06.05.2026 16:08:05 Enterprise HaiWell HaiWell — M1 Определён, Вкл
06.05.2026 16:08:43 Enterprise HaiWell HaiWell — M0 Определён, Вкл
06.05.2026 16:26:52 Enterprise HaiWell HaiWell — M0 Хороший, Откл
06.05.2026 16:26:52 Enterprise HaiWell HaiWell — M1 Хороший, Откл
06.05.2026 16:26:53 Enterprise HaiWell HaiWell — M0 Определён, Откл
06.05.2026 16:26:53 Enterprise HaiWell HaiWell — M1 Определён, Откл
06.05.2026 16:27:04 Enterprise HaiWell HaiWell — M1 Определён, Вкл
06.05.2026 16:27:05 Enterprise HaiWell HaiWell — M0 Определён, Вкл
06.05.2026 16:27:28 Enterprise HaiWell HaiWell — M0 Хороший, Откл
06.05.2026 16:27:28 Enterprise HaiWell HaiWell — M1 Хороший, Откл
06.05.2026 16:27:29 Enterprise HaiWell HaiWell — M0 Определён, Вкл
06.05.2026 16:27:29 Enterprise HaiWell HaiWell — M1 Определён, Вкл
06.05.2026 16:27:30 Enterprise HaiWell HaiWell — M0 Определён, Откл
06.05.2026 16:27:30 Enterprise HaiWell HaiWell — M1 Определён, Откл
06.05.2026 16:27:43 Enterprise HaiWell HaiWell — M1 Определён, Вкл
06.05.2026 16:27:43 Enterprise HaiWell HaiWell — M0 Определён, Вкл
06.05.2026 16:28:28 Enterprise HaiWell HaiWell — M0 Хороший, Откл
06.05.2026 16:28:28 Enterprise HaiWell HaiWell — M1 Хороший, Откл
06.05.2026 16:28:29 Enterprise HaiWell HaiWell — M0 Определён, Вкл
06.05.2026 16:28:29 Enterprise HaiWell HaiWell — M1 Определён, Вкл
06.05.2026 16:28:29 Enterprise HaiWell HaiWell — M0 Определён, Откл
06.05.2026 16:28:29 Enterprise HaiWell HaiWell — M1 Определён, Отклвот прям логи, тут я игрался со статусами, вдруг это триггер на изменение команды сразу будет, но нет
там где статус Хороший это отложенная по какой то причине команда на изменение по mqtt, в них видно период ровно в 1 минуту, хотя отправлял я их сразу после включения каналов вручную без mqtt2026-05-06 16:26:52 Приём myparam2 = {
«test»: {
«i…
Подписанные устройства: 2
Hello from JS. Topic: myparam22026-05-06 16:27:11 Приём myparam2 = {
«test»: {
«i…
Подписанные устройства: 2
Hello from JS. Topic: myparam22026-05-06 16:27:52 Приём myparam2 = {
«test»: {
«i…
Подписанные устройства: 2
Hello from JS. Topic: myparam206.05.2026 в 16:40 #43239
manjey73УчастникОставьте в опросе Modbus только один регистр на опрос, в который вы отправляете команду. И сделайте то же самое.
Сколько времени пройдет?
06.05.2026 в 16:42 #43240IvanovVladimir
УчастникУже пробовал, лог получаю аналогичный
06.05.2026 в 16:45 #43243IvanovVladimir
УчастникДанная ошибка у меня возникает только с условием, если значение посылаемое по mqtt совпадает с тем значением канала к которому она привязана. Если текущее значение привязанного канала не совпадает с тем, что было получено в команде тогда отправка команды на плк происходит сразу.
06.05.2026 в 16:50 #43244
manjey73Участникааа, тогда возможно надо что-то в коде добавить или изменить, чтобы все равно отправить.
Откровенно говоря, я у себя наоборот делал, чтобы ничего не отправлялось, если значение совпадает, какой в этом смысл?07.05.2026 в 07:34 #43256IvanovVladimir
УчастникЕсть два канала, 101 и 102
101 канал привязан к регистру плк через ModBusTCP
102 канал привязан к значению получаемого пакета MQTT
Запускаем веб
101 — 1
102 — —
отправляем сообщение по mqtt со значением 0
101 — 0 (изменена моим модулем)
102 — 0
*отправлена команда в ПЛК в связи с изменением значения канала 101
в вебе изменяем значение канала 101 на 1
101 — 1
102 — 0
*отправлена команда в ПЛК в связи с изменением значения канала 101
отправляем сообщение по mqtt со значением 0, чтобы отключить регистр в ПЛК ранее включенный через вебморду скады
101 — 1
102 — 0
*ждем до минуты пока сервер просканирует архив (я предполагаю что он это делает)
101 — 0 (изменена моим модулем)
102 — 0
*отправлена команда в ПЛК в связи с изменением значения канала 101
отправляем сообщение по mqtt со значением 1
101 — 1 (изменена моим модулем)
102 — 1
*отправлена команда в ПЛК в связи с изменением значения канала 101То есть ждать отправки команды на плк приходится только в тех случаях когда значение канала 102 совпадает с тем значением что я вновь передаю на него по mqtt
Алгоритм программы которая мне нужна максимально на самом деле прост:
1) создается таблица привязок в свойствах модуля, где я указываю из какого канала (Х) в какой (У) мне необходимо передать значение (в примере из канала 102 в канал 101)
2) при получении нового значения на Х, проверяется есть ли разница между полученным сообщением и значением У
3) если значения разные то необходимо изменить значение У на значение Х, что должно приводить к немедленной отправки команды на ПЛКЕсли обобщить я хочу иметь возможность управлять ПЛК не только из веб-морды скады, но и используя команды mqtt из внешней системы. Чтобы я мог изменить значение регистров ПЛК как по MQTT, так и непосредственно из интерфейса скады
07.05.2026 в 07:36 #43257IvanovVladimir
УчастникДля реализации такого управления я начал писать модуль который будет перебрасывать значения с каналов mqtt на каналы modbustcp, чтобы посредством этого отправлялись команды на ПЛК
07.05.2026 в 09:16 #43258
manjey73УчастникА почему вы не используете метод
public override void OnIteration()у него вызов раз 10 в секунду.07.05.2026 в 09:27 #43259IvanovVladimir
УчастникЭто будет сильно нагружать систему ведь мне придется каждую итерацию опрашивать все каналы и при различии применять изменения, думаю при 5к+ каналов это начнет люто тормозить. В то время как OnCurrentDataProcessed вызывается по событию, что более правильно.
07.05.2026 в 10:09 #43260IvanovVladimir
УчастникВ целом мой метод работает идеально, кроме случая когда я получаю по mqtt такое же значение, как в канале к нему привязанном, не в канале который отправляет данные на плк по modbustcp, а в канале который привязан к данному mqtt. Почему то конкретно в этом случае изменение канала modbus идет с задержкой. Вопрос в том как мне искусственно кодом триггернуть сиюминутное изменение канала modbus и отправки команды на ПЛК? Что такого происходит когда значения канала mqtt отличается от полученного сообщения, чего не происходит когда они одинаковые
-
Тема изменена 1 месяц, 1 неделя назад пользователем
-
АвторСообщения
- Для ответа в этой теме необходимо авторизоваться.