PDA

Просмотр полной версии : ПР200. Изменение состояния по изменению сетевой переменной. Как?



sokolov.sv
09.03.2024, 23:30
Имеется такой блок.
74197

На I1(2) импульсная кнопка, на Q7(2) реле включения/выключения света. Логика такая, одно нажатие включить свет, следующее выключить и т.д, т.е. схема toggle.

Проблема в следующем. Если изменение состояния выхода Q7(2) происходит только по импульсу на входе I1(2), то все работает корректно. Но как видно, изменить состояние Q7(2) можно и с помощью изменения сетевой переменной. В этом случае на выходе макроса ON_OFF остается прежнее значение и чтобы опять все заработало корректно, нужно дернуть импульсную кнопку 2 раза.

Пример проблемного состояния.
74198

Как можно сделать по другому? Чтобы по изменению сетевой переменной, состояние на выходе ON_OFF тоже устанавливалось в значение сетевой переменной?

Godlike_S
10.03.2024, 03:08
Имеется такой блок.
74197

На I1(2) импульсная кнопка, на Q7(2) реле включения/выключения света. Логика такая, одно нажатие включить свет, следующее выключить и т.д, т.е. схема toggle.

Проблема в следующем. Если изменение состояния выхода Q7(2) происходит только по импульсу на входе I1(2), то все работает корректно. Но как видно, изменить состояние Q7(2) можно и с помощью изменения сетевой переменной. В этом случае на выходе макроса ON_OFF остается прежнее значение и чтобы опять все заработало корректно, нужно дернуть импульсную кнопку 2 раза.

Пример проблемного состояния.
74198

Как можно сделать по другому? Чтобы по изменению сетевой переменной, состояние на выходе ON_OFF тоже устанавливалось в значение сетевой переменной?

Вам нужно синхронизировать все с сетевыми переменными, это сделать можно например вот так:

74199

У Вас в качестве мастера что используется? Использовать целый регистр для управления одним устройствам по меньшей мере расточительно (в одном регистре можно передать 16 состояний с помощью битовой маски).

EFrol
10.03.2024, 08:07
Прошу прощения! А я просто инвертирую бит в сетевой переменной.
74203

Одна переменная 32 комнаты:
74204

Но мне больше по душе:
74205

Сергей0308
10.03.2024, 08:24
Имеется такой блок.
74197

На I1(2) импульсная кнопка, на Q7(2) реле включения/выключения света. Логика такая, одно нажатие включить свет, следующее выключить и т.д, т.е. схема toggle.

Проблема в следующем. Если изменение состояния выхода Q7(2) происходит только по импульсу на входе I1(2), то все работает корректно. Но как видно, изменить состояние Q7(2) можно и с помощью изменения сетевой переменной. В этом случае на выходе макроса ON_OFF остается прежнее значение и чтобы опять все заработало корректно, нужно дернуть импульсную кнопку 2 раза.

Пример проблемного состояния.
74198

Как можно сделать по другому? Чтобы по изменению сетевой переменной, состояние на выходе ON_OFF тоже устанавливалось в значение сетевой переменной?

Вот здесь подобное делали 2 года тому назад, в смысле, управление Т-триггерами локально, с кнопок ПР и по сети, с другого ПР:
https://owen.ru/forum/showthread.php?t=26216&page=222

74206

sokolov.sv
10.03.2024, 13:56
Вам нужно синхронизировать все с сетевыми переменными, это сделать можно например вот так:

74199

У Вас в качестве мастера что используется? Использовать целый регистр для управления одним устройствам по меньшей мере расточительно (в одном регистре можно передать 16 состояний с помощью битовой маски).

В качестве мастера HomeAssistant через шлюз MODBUS TCP -> MODBUS RTU
С регистрами согласен, расточительно, но пока переделывать не буду, т.к. даже в варианте 1 выключатель - 1 переменная еще есть приличный запас с учетом того, что вся схема уже реализована. Ну и в HomeAssistant для записи битовых масок в регистры нужно немного повозиться. За идею спасибо!

sokolov.sv
10.03.2024, 14:26
Прошу прощения! А я просто инвертирую бит в сетевой переменной.
74203

Одна переменная 32 комнаты:
74204

Но мне больше по душе:
74205

Спасибо! Пожалуй третий вариант и возьму как основной. Тут макрос напрашивается, где на входе сигнал с кнопки + сетевая переменная (если битовую маску исопльзовать, то еще она).

Dimensy
10.03.2024, 14:37
Спасибо! Пожалуй третий вариант и возьму как основной. Тут макрос напрашивается, где на входе сигнал с кнопки + сетевая переменная (если битовую маску исопльзовать, то еще она).
Ну, если вам не нужна битовая маска, то тогда так проще
74218

Сергей0308
10.03.2024, 15:18
В смысле, не нужна?
Если кого-то, вследствие непонимания или принципа "и так сойдёт" это устраивает, то большинство пользователей это не устроит, в смысле, решение должно быть более-менее оптимальным.
Сегодня у него одна лампочка, завтра захочет 8 или 16 лампочками управлять! Кроме, того, так это просто не логично, в смысле затратить в 16 раз больше ресурсов чем требуется!

sokolov.sv
10.03.2024, 16:17
Делаю для себя, а не для заказчика. Вообще я всю сознательную жизнь программирую на императивных языках, с FBD после этого чуть сложнее работать. Иногда даже хочется многие блоки на ST. Так вот всегда придерживаюсь правила: преждевременная оптимизация - это зло. Исходные данные: ПР200 имеет 64 регистра, на данный момент в проекте задействовано 49, при том, что задействованы 24 DO (с 2хПРМ) и все 4xAI и расширения не предвидится. Ядро системы все таки HomeAssistant, а ПР200 для него периферия, которая обеспечивает проводную автоматизацию, а у меня на нем еще и ZigBee и LoRaWAN.

Что там потребуется расширять, если все провода уже заложены и новых не будет? Это не условия предприятия, где в слаботочные лотки можно доложить кабеля ;-)

Почему еще без явной необходимости не вижу смысла в битовых масках - усложнение понимания. Когда тебе нужно помнить за что отвечает тот или иной бит переменной. Это неважно, если ПР200 больше ни с чем не взаимодействует, но если взаимодействуте, то это может стать головной болью.

kondor3000
10.03.2024, 16:27
Делаю для себя, а не для заказчика. Вообще я всю сознательную жизнь программирую на императивных языках, с FBD после этого чуть сложнее работать. Иногда даже хочется многие блоки на ST. Так вот всегда придерживаюсь правила: преждевременная оптимизация - это зло. Исходные данные: ПР200 имеет 64 регистра, на данный момент в проекте задействовано 49, при том, что задействованы 24 DI (с 2хПРМ) и все 4xAI и расширения не предвидится. Ядро системы все таки HomeAssistant, а ПР200 для него периферия, которая обеспечивает проводную автоматизацию, а у меня на нем еще и ZigBee и LoRaWAN.

Что там потребуется расширять, если все провода уже заложены и новых не будет? Это не условия предприятия, где в слаботочные лотки можно доложить кабеля ;-)

Почему еще без явной необходимости не вижу смысла в битовых масках - усложнение понимания. Когда тебе нужно помнить за что отвечает тот или иной бит переменной. Это неважно, если ПР200 больше ни с чем не взаимодействует, но если взаимодействуте, то это может стать головной болью.

Зря вы так думаете, вот пример, правда это справедливо если ПР мастер. У вас всё быстрее, так как ПР слейв.
У вас 49 регистров передаются грубо по 100 ms на регистр итого 49*0.1 сек=4,9 секунд (у ПР мастера нет группового опроса),
если вы уберёте 32 булевых переменных в 2 маски, останется 19 регистров и время передачи уменьшится до 1,9 секунды. В три раза быстрее !!!

sokolov.sv
10.03.2024, 18:38
Ну вот поэтому я и говорю, что все всегда зависит от конкретных условий. В условиях: 1) ПР - мастер, 2) большое количество булевых состояний, 3) потенциальная вероятность увеличения кол-ва состояний, естественно без битовой маски задача не решается. У меня же условия по всем пунктам прямо противоположные. Всем большое спасибо за помощь! Все примеры интересные, возможно будут применены где-то в будущем.

В дополнении видится еще одна потенциальная проблема с битовыми масками в таком кейсе как у меня. Дело в том, что HA через MODBUS TCP записывает значение регистра, предварительно считывая его, работает он при этом в многопоточном режиме. Думаю догадываетесь, что есть ненулевая вероятность некорректной работы в таком варианте. Сомневаюсь, что на чтение-запись регистров в HA стоят блокировки, хотя может и ошибаюсь, требует проверки.

sokolov.sv
10.03.2024, 19:42
При TCP вообще смешно говорить о чем-то кроме 64 регистров сразу.
Согласен! Но HA так не делает. Все таки дергает по одному.
В случае "прочитать сразу 64" проблема многопоточности еще более актуальна и вероятность проблемы повышается, теряется атомарность действия как и в случае с битовой маской.

sokolov.sv
10.03.2024, 21:29
Если бы я разрабатывал HA, то я бы конечно учел и поставил блокировки и на чтение и на запись. Но, это не мой код и неправильно рассуждать в таком ключе. Опять же я не уверен, что блокировок там нет, писал ранее, что требует проверки.
Поймите это не SCADA и возможности там более скудные по работе с MODBUS TCP, Он умеет взять последовательность регистров скажем с 100 по 110 и раскидать в однотипные переменные, но опять же это не 64 за раз, это все равно несколько опросов скажем 3-4, и это еще при условии, что переменные одного типа в ПР хранятся последовательно, а это зачастую не так. Более того в отличии от вас я в этом не вижу проблемы. 10 мс на запрос перед изменением и записью, это вообще не стоит обсуждения.


Если HA так не может - в помойку. Ищите что-нить поприличней.
Что например? Из альтернатив только OpenHub, но это больше вопрос предпочтений.

sokolov.sv
10.03.2024, 22:46
Причем тут шлюз? Понятно, что шлюз MODBUS TCP <-> MODBUS RTU работает в однопоточном (блокирующем) режиме. А приложение которое работает с шлюзом не может работать в многопоточном!? Если не понимаете где тут проблема, могу пошагово описать чего стоит ждать.

P.S.: На будущее, подобного класса шлюзы бывают более умные и умеют очередь внутри! Конкретно в моем случае он недорогой и этого функционала не имеет.
P.S.S.: Может непонятно что такое HA? Это вот https://www.home-assistant.io конкретно про модуль Modbus мастера в нем вот https://www.home-assistant.io/integrations/modbus/

sokolov.sv
11.03.2024, 00:23
опишите

Условия такие:
- HA всегда перед тем как изменить значение регистра запрашивает его актуальное значение
- начальное состояние регистра с битовой маской: 0x0000 - все выключено
- За состояние Lamp1 отвечает бит 0
- За состояние Lamp2 отвечает бит 1

Поток1
HA - читает регистр, чтобы узнать состояние Lamp1 (прочитал 0x0000)
Поток 2
HA - читает регистр, чтобы узнать состояние Lamp2 (прочитал 0x0000)
Поток1
HA - изменеят текущее состояние бита 0 так, чтобы включить Lamp1 (0x0001)
Поток2
HA - изменеят текущее состояние бита 1 так, чтобы включить Lamp2 (0x0002)

Ожидаемый результат:
Lamp1 и Lamp2 включены
Реальный результат:
Включен только Lamp2, т.к Lamp1 на последней операции будет выключен.

Если брать случай с "хранить состояние в отдельных регистрах и читать 64 регистра за раз", то при записи будет все хорошо, т.к. пишем всегда 1 регистр, а вот при отображении текущего состояния может быть та же проблема. Надо приводить пример как она может возникнуть? Суть то та же, прочитано значение, а оно уже в регистрах изменено другим потоком.



Заместо ЖД в деревню Вилабаджо построили многотелепортовый запулятор. Мэр Вилабаджо выступил с речью что теперь каждый назависимо от других может приехать и уехать. Очереди на вокзале теперь нет. Но запулятор был построен на другом берегу реки, на которой была только 1 лодка.
Да, все именно так. Имеет право на жизнь. Как разница где будет реализован монопольный доступ к интерфейсу в устройстве или в софте/клиенте?

sokolov.sv
11.03.2024, 00:36
про "каждые 15 секунд" забыли.
Опуститесь ниже на пяток абзацев до букв CONFIGURATION VARIABLES и найдите про custom
Это кастомный тип для чтения одной метрики через распаковку средствами питоновского unpack, а не распкаовка всех 64 регистров в нужные типы.
В HA только однотипные данные можно считать последовательно и распаковать за раз через опцию slave_count/virtual_count

sokolov.sv
11.03.2024, 04:16
Ну продолжайте создавать сами себе проблемы и после про них расказывать.

Поток1
Вообще ничего не читает, а при небходимости посылает маску с нужными битами для Lamp1 ... Lamp16 которые нужно инвертировать.

ПР
текущая маска := текущая маска xor сетевая маска
сетевая маска := 0;
Lamp1 := текущая маска.0
..
Lamp16 := текущая маска.15

Ожидаемый результат = Реальный результат


Действительно. Разницы никакой, зато есть потоки.

Т.е. к формальной логике вопросов нет? Проблема все таки будет при таких вводных?
Написали бы сразу, что с HA и подобным софтом не работали и закрыли бы вопрос. Вы же пытаетесь нафантазировать то, чего нет. Т.е. я написал вводные, а вы говорите давайте их изменим, они неправильные. Ну давайте изменим, добро пожаловать в команду HA, софт открытый, можете сделать МР и отправить, может примут. Должна быть блокировка при такой логике, есть она или нет, нужно выяснять (третий раз пишу уже). Я лишь пытался сказать, что подход 1 регистр - 1 состояние делает невозможным подобную проблему и всего-то.

sokolov.sv
11.03.2024, 04:36
Ой. Т.е. нужно попрограммировать? Не, не надо))
Во-первых вы все таки неправильно поняли документацию в силу того, что незнакомы с HA. Я же написал конкретно, что распаковать 64 за раз не получится (второй раз пишу)! Частный случай - это когда все данные одного типа, регистры идут без пропусков - в таком варианте получится за раз.

С такими параметрами:
data_type: int16
slave_count: 64
Получу на выходе 64 значения int16 с которыми дальше можно работать.

Или:
data_type: custom
structure: ">f"
slave_count: 32
Получу на выходе 32 значения float big-endian


Догадались, что нужно будет сделать если в регистрах значения не одного типа?

Вот такой вариант, к сожалению невозможен. Думаете в таком варианте получите float и int? Нет! Это просто не заработает.
data_type: custom
structure: ">fi"

Хотя в самом Python допустима любой pack/unpack, примеры: https://docs.python.org/3/library/struct.html#examples

Во-вторых невнимательно читали топик, писал ранее, что программировал на императивных языках всю сознательную жизнь (более 20 лет) и видимо пропустил за это время когда это "задать аргументы для unpack" стало называться программированием? Может еще и regexp, pcre к программированию относите? )

capzap
11.03.2024, 08:48
ну началось, вход пошли аргументы программирования, это предложение померятся?
когда пишите
Написали бы сразу, что с HA и подобным софтом не работали и закрыли бы вопрос. Вы же пытаетесь нафантазировать то, чего нет.А Вы что то предоставили наглядное или все должны верить Вашим фантазиям?
Почему в качестве примера берете data_type в котором нет типа вроде coil, взяли бы адекватную конфигурацию и вот действительно бы вопросы отпали, а то рассказываете здесь что пока достаточно одного регистра на один дискретный сигнал
Например Configuring switch entities чем не пример , документация ПР200 позволяет реализовать управление битами а читать регистр 74223 и 74224

sokolov.sv
11.03.2024, 14:32
Мерятся задачи нет. Я не меряюсь в том, в чем плохо разбираюсь. Коллега вот пробует.
Предложение хорошее с использованием Coil, но тоже требует изучения, т.к. в документации написано, что может неправильно работать с устройствами с общей памятью, т.е. в том случае когда, как я понял (поправьте если не прав), и Holding и Coll регистры используют общую память. Последний ваш скрин с документации говорит как раз об этом?

capzap
11.03.2024, 14:48
в документации написано, что может неправильно работать с устройствами с общей памятью, т.е. в том случае когда, как я понял (поправьте если не прав), и Holding и Coll регистры используют общую память. Последний ваш скрин с документации говорит как раз об этом?
там написана муть, не приводящая ни к каким выводам, возможно у составителя документации случился какой то конфуз с общей памятью, но в промавтоматике это ни кому не мешает