|
UniSet
2.8.0
|
Открытые члены | |
| MBTCPMultiMaster (uniset::ObjectId objId, uniset::ObjectId shmID, const std::shared_ptr< SharedMemory > &ic=nullptr, const std::string &prefix="mbtcp") | |
| virtual uniset::SimpleInfo * | getInfo (const char *userparam=0) override |
Открытые члены унаследованные от uniset::MBExchange | |
| MBExchange (uniset::ObjectId objId, uniset::ObjectId shmID, const std::shared_ptr< SharedMemory > &ic=nullptr, const std::string &prefix="mb") | |
| void | printMap (RTUDeviceMap &d) |
| void | execute () |
| std::shared_ptr< LogAgregator > | getLogAggregator () |
| std::shared_ptr< DebugStream > | log () |
Открытые члены унаследованные от uniset::UniSetObject | |
| UniSetObject (const std::string &name, const std::string §ion) | |
| UniSetObject (uniset::ObjectId id) | |
| virtual CORBA::Boolean | exist () override |
| virtual uniset::ObjectId | getId () override |
| const uniset::ObjectId | getId () const |
| std::string | getName () const |
| virtual uniset::ObjectType | getType () override |
| const std::string | getStrType () |
| virtual uniset::SimpleInfo * | apiRequest (const char *query) override |
| virtual void | push (const uniset::TransportMessage &msg) override |
| поместить сообщение в очередь Подробнее... | |
| virtual void | pushMessage (const char *msg, ::CORBA::Long mtype, const ::uniset::Timespec &tm, const ::uniset::ProducerInfo &pi, ::CORBA::Long priority, ::CORBA::Long consumer) override |
| поместить текстовое сообщение в очередь Подробнее... | |
| virtual Poco::JSON::Object::Ptr | httpGet (const Poco::URI::QueryParameters &p) override |
| virtual Poco::JSON::Object::Ptr | httpHelp (const Poco::URI::QueryParameters &p) override |
| uniset::ObjectPtr | getRef () const |
| std::shared_ptr< UniSetObject > | get_ptr () |
| virtual timeout_t | askTimer (uniset::TimerId timerid, timeout_t timeMS, clock_t ticks=-1, uniset::Message::Priority p=uniset::Message::High) override |
Открытые члены унаследованные от uniset::LT_Object | |
| timeout_t | checkTimers (UniSetObject *obj) |
| timeout_t | getTimeInterval (uniset::TimerId timerid) const |
| timeout_t | getTimeLeft (uniset::TimerId timerid) const |
Открытые члены унаследованные от uniset::UHttp::IHttpRequest | |
| virtual Poco::JSON::Object::Ptr | httpRequest (const std::string &req, const Poco::URI::QueryParameters &p) |
Открытые статические члены | |
| static std::shared_ptr< MBTCPMultiMaster > | init_mbmaster (int argc, const char *const *argv, uniset::ObjectId shmID, const std::shared_ptr< SharedMemory > &ic=nullptr, const std::string &prefix="mbtcp") |
| static void | help_print (int argc, const char *const *argv) |
Открытые статические члены унаследованные от uniset::MBExchange | |
| static void | help_print (int argc, const char *const *argv) |
| static DeviceType | getDeviceType (const std::string &dtype) noexcept |
| static std::ostream & | print_plist (std::ostream &os, const PList &p) |
Защищенные члены | |
| virtual void | sysCommand (const uniset::SystemMessage *sm) override |
| virtual void | initIterators () override |
| virtual std::shared_ptr< ModbusClient > | initMB (bool reopen=false) override |
| virtual bool | deactivateObject () override |
| Деактивация объекта (переопределяется для необходимых действий при завершении работы) Подробнее... | |
| void | initCheckConnectionParameters () |
| void | poll_thread () |
| void | check_thread () |
| void | final_thread () |
Защищенные члены унаследованные от uniset::MBExchange | |
| virtual void | step () |
| virtual void | sensorInfo (const uniset::SensorMessage *sm) override |
| virtual void | timerInfo (const uniset::TimerMessage *tm) override |
| virtual void | askSensors (UniversalIO::UIOCommand cmd) |
| virtual void | initOutput () |
| virtual bool | activateObject () override |
| Активизация объекта (переопределяется для необходимых действий после активизации) Подробнее... | |
| virtual void | initValues () |
| void | firstInitRegisters () |
| bool | preInitRead (InitList::iterator &p) |
| bool | initSMValue (ModbusRTU::ModbusData *data, int count, RSProperty *p) |
| virtual bool | poll () |
| bool | pollRTU (std::shared_ptr< RTUDevice > &dev, RegMap::iterator &it) |
| void | updateSM () |
| void | updateRTU (RegMap::iterator &it) |
| void | updateMTR (RegMap::iterator &it) |
| void | updateRTU188 (RegMap::iterator &it) |
| void | updateRSProperty (RSProperty *p, bool write_only=false) |
| virtual void | updateRespondSensors () |
| bool | isUpdateSM (bool wrFunc, long devMode) const noexcept |
| bool | isPollEnabled (bool wrFunc) const noexcept |
| bool | isSafeMode (std::shared_ptr< RTUDevice > &dev) const noexcept |
| bool | isProcActive () const |
| void | setProcActive (bool st) |
| bool | waitSMReady () |
| void | readConfiguration () |
| bool | readItem (const std::shared_ptr< UniXML > &xml, UniXML::iterator &it, xmlNode *sec) |
| bool | initItem (UniXML::iterator &it) |
| void | initDeviceList () |
| void | initOffsetList () |
| std::shared_ptr< RTUDevice > | addDev (RTUDeviceMap &dmap, ModbusRTU::ModbusAddr a, UniXML::iterator &it) |
| std::shared_ptr< RegInfo > | addReg (std::shared_ptr< RegMap > &devices, ModbusRTU::RegID id, ModbusRTU::ModbusData r, UniXML::iterator &it, std::shared_ptr< RTUDevice > dev) |
| RSProperty * | addProp (PList &plist, RSProperty &&p) |
| bool | initMTRitem (UniXML::iterator &it, std::shared_ptr< RegInfo > &p) |
| bool | initRTU188item (UniXML::iterator &it, std::shared_ptr< RegInfo > &p) |
| bool | initRSProperty (RSProperty &p, UniXML::iterator &it) |
| bool | initRegInfo (std::shared_ptr< RegInfo > &r, UniXML::iterator &it, std::shared_ptr< RTUDevice > &dev) |
| bool | initRTUDevice (std::shared_ptr< RTUDevice > &d, UniXML::iterator &it) |
| virtual bool | initDeviceInfo (RTUDeviceMap &m, ModbusRTU::ModbusAddr a, UniXML::iterator &it) |
| std::string | initPropPrefix (const std::string &def_prop_prefix="") |
| void | rtuQueryOptimization (RTUDeviceMap &m) |
| void | rtuQueryOptimizationForDevice (const std::shared_ptr< RTUDevice > &d) |
| void | rtuQueryOptimizationForRegMap (const std::shared_ptr< RegMap > ®map) |
Защищенные члены унаследованные от uniset::UniSetObject | |
| virtual void | processingMessage (const uniset::VoidMessage *msg) |
| virtual void | onTextMessage (const uniset::TextMessage *tm) |
| VoidMessagePtr | receiveMessage () |
| VoidMessagePtr | waitMessage (timeout_t msec=UniSetTimer::WaitUpTime) |
| void | termWaiting () |
| size_t | countMessages () |
| size_t | getCountOfLostMessages () const |
| void | uterminate () |
| void | thread (bool create) |
| void | offThread () |
| void | onThread () |
| virtual void | callback () |
| void | setID (uniset::ObjectId id) |
| void | setThreadPriority (Poco::Thread::Priority p) |
| void | setMaxSizeOfMessageQueue (size_t s) |
| size_t | getMaxSizeOfMessageQueue () const |
| bool | isActive () const |
| void | setActive (bool set) |
| virtual Poco::JSON::Object::Ptr | httpGetMyInfo (Poco::JSON::Object::Ptr root) |
| Poco::JSON::Object::Ptr | request_conf (const std::string &req, const Poco::URI::QueryParameters &p) |
| Poco::JSON::Object::Ptr | request_conf_name (const std::string &name, const std::string &props) |
Защищенные члены унаследованные от uniset::LT_Object | |
| virtual std::string | getTimerName (int id) const |
| TimersList | getTimersList () const |
Защищенные данные | |
| uniset::uniset_rwmutex | mbMutex |
| bool | force_disconnect |
| timeout_t | checktime |
Защищенные данные унаследованные от uniset::MBExchange | |
| bool | allInitOK |
| RTUDeviceMap | devices |
| InitList | initRegList |
| xmlNode * | cnode = { 0 } |
| std::string | s_field |
| std::string | s_fvalue |
| std::shared_ptr< SMInterface > | shm |
| timeout_t | initPause = { 3000 } |
| uniset::uniset_rwmutex | mutex_start |
| bool | force = { false } |
| bool | force_out = { false } |
| bool | mbregFromID = { false } |
| timeout_t | polltime = { 100 } |
| timeout_t | sleepPause_msec = { 10 } |
| size_t | maxQueryCount = { ModbusRTU::MAXDATALEN } |
| PassiveTimer | ptHeartBeat |
| uniset::ObjectId | sidHeartBeat = { uniset::DefaultObjectId } |
| long | maxHeartBeat = { 10 } |
| IOController::IOStateList::iterator | itHeartBeat |
| uniset::ObjectId | test_id = { uniset::DefaultObjectId } |
| uniset::ObjectId | sidExchangeMode = { uniset::DefaultObjectId } |
| IOController::IOStateList::iterator | itExchangeMode |
| long | exchangeMode = { emNone } |
| std::atomic_bool | activated = { false } |
| std::atomic_bool | canceled = { false } |
| timeout_t | activateTimeout = { 20000 } |
| bool | noQueryOptimization = { false } |
| bool | notUseExchangeTimer = { false } |
| std::string | prefix |
| timeout_t | stat_time = { 0 } |
| size_t | poll_count = { 0 } |
| PassiveTimer | ptStatistic |
| std::string | statInfo = { "" } |
| std::string | prop_prefix |
| std::shared_ptr< ModbusClient > | mb |
| timeout_t | recv_timeout = { 500 } |
| timeout_t | default_timeout = { 5000 } |
| timeout_t | aftersend_pause = { 0 } |
| PassiveTimer | ptReopen |
| Trigger | trReopen |
| PassiveTimer | ptInitChannel |
| ThresholdList | thrlist |
| std::string | defaultMBtype |
| std::string | defaultMBaddr |
| bool | defaultMBinitOK = { false } |
| std::shared_ptr< LogAgregator > | loga |
| std::shared_ptr< DebugStream > | mblog |
| std::shared_ptr< LogServer > | logserv |
| std::string | logserv_host = {""} |
| int | logserv_port = {0} |
| const std::shared_ptr< SharedMemory > | ic |
| VMonitor | vmon |
| size_t | ncycle = { 0 } |
Защищенные данные унаследованные от uniset::UniSetObject | |
| std::shared_ptr< UInterface > | ui |
| std::string | myname |
| std::weak_ptr< UniSetManager > | mymngr |
Защищенные данные унаследованные от uniset::LT_Object | |
| timeout_t | sleepTime |
Дополнительные унаследованные члены | |
Открытые типы унаследованные от uniset::MBExchange | |
| enum | ExchangeMode { emNone = 0, emWriteOnly = 1, emReadOnly = 2, emSkipSaveToSM = 3, emSkipExchange = 4 } |
| enum | SafeMode { safeNone = 0, safeResetIfNotRespond = 1, safeExternalControl = 2 } |
| enum | DeviceType { dtUnknown, dtRTU, dtMTR, dtRTU188 } |
| enum | Timer { tmExchange } |
| typedef std::list< RSProperty > | PList |
| typedef std::map< ModbusRTU::RegID, std::shared_ptr< RegInfo > > | RegMap |
| typedef std::unordered_map< ModbusRTU::ModbusAddr, std::shared_ptr< RTUDevice > > | RTUDeviceMap |
Защищенные типы унаследованные от uniset::MBExchange | |
| typedef std::list< InitRegInfo > | InitList |
| typedef std::list< IOBase > | ThresholdList |
Защищенные типы унаследованные от uniset::LT_Object | |
| typedef std::deque< TimerInfo > | TimersList |
\page page_ModbusTCPMulti Реализация ModbusTCP 'multi' master
- \ref sec_MBTCPM_Comm
- \ref sec_MBTCPM_Conf
- \ref sec_MBTCPM_ConfList
- \ref sec_MBTCPM_ExchangeMode
- \ref sec_MBTCPM_CheckConnection
\section sec_MBTCPM_Comm Общее описание ModbusTCPMultiMaster
Класс реализует процесс обмена (опрос/запись) с RTU-устройствами,
через TCP-шлюз. Список регистров с которыми работает процесс задаётся в конфигурационном файле
в секции \b <sensors>. см. \ref sec_MBTCPM_Conf
При этом для шлюза можно задавать несколько ip-адресов (см. <GateList>), если связь пропадает по
одному каналу (ip), то происходит переключение на другой канал (через timeout мсек), если пропадает
с этим каналом, то переключается на следующий и так по кругу (в порядке уменьшения приоритета, задаваемого
для каждого канала (cм. <GateList> \a priority).
\section sec_MBTCPM_Conf Конфигурирование ModbusTCPMultiMaster
Конфигурирование процесса осуществляется либо параметрами командной строки либо
через настроечную секцию.
\par Секция с настройками
При своём старте, в конфигурационном файле ищётся секция с названием объекта,
в которой указываются настроечные параметры по умолчанию.
Пример:
\code
<MBMaster1 name="MBMaster1" polltime="200" channelTimeout="..." exchangeModeID="..">
<DeviceList>
<item addr="0x01" respondSensor="RTU1_Not_Respond_FS" force="0" timeout="2000" invert="1"/>
<item addr="0x02" respondSensor="RTU2_Respond_FS" timeout="2000" invert="0"/>
</DeviceList>
<GateList>
<item ip="" port="" respond_id="" priority="" force=""/>
<item ip="" port="" respond_id="" priority="" respond_invert="1"/>
<GateList>
</MBMaster1>
\endcode
- \b channelTimeout - умолчательный timeout для переключения каналов. По умолчанию: берётся общий defaultTimeout.
Секция <DeviceList> позволяет задать параметры обмена с конкретным RTU-устройством.
- \b addr - адрес устройства для которого, задаются параметры
- \b timeout msec - таймаут, для определения отсутствия связи
- \b invert - инвертировать логику. По умолчанию датчик выставляется в "1" при \b наличии связи.
- \b respondSensor - идентификатор датчика связи (DI).
- \b force [1,0] - "1" - обновлять значение датчика связи в SM принудительно на каждом цикле проверки ("0" - только по изменению).
- \b exchangeModeID - идентификатор датчика режима работы (см. MBExchange::ExchangeMode).
- \b ask_every_reg - 1 - опрашивать ВСЕ регистры подряд, не обращая внимания на timeout. По умолчанию - "0" Т.е. опрос устройства (на текущем шаге цикла опроса), прерывается на первом же регистре, при опросе которого возникнет timeout.
- \b safemodeXXX - см. \ref sec_MBTCP_SafeMode
Секция <GateList> позволяет задать несколько каналов связи со Slave-устройством. Это удобно для случая, когда Slave имеет
более одного канала связи с ним (основной и резервный например).
- \b ip - ip-адрес
- \b port - порт
- \b respond - датчик связи по данному каналу (помимо обобщённого)
- \b priority - приоритет канала (чем больше число, тем выше приоритет)
- \b respond_invert - инвертировать датчик связи (DI)
- \b force [1,0] - "1" - обновлять значение датчика связи в SM принудительно на каждом цикле проверки ("0" - только по изменению).
- \b timeout - таймаут на определение отсутствия связи для данного канала. По умолчанию берётся глобальный.
- \b checkFunc - Номер функции для проверки соединения
- \b checkAddr - Адрес устройства для проверки соединения
- \b checkReg - Регистр для проверки соединения
\par Параметры запуска
При создании объекта в конструкторе передаётся префикс для определения параметров командной строки.
По умолчанию \b xxx="mbtcp".
Далее приведены основные параметры:
\b --xxx-name ID - идентификатор процесса.
IP-адрес шлюза задаётся параметром в конфигурационном файле \b gateway_iaddr или
параметром командной строки \b --xxx-gateway-iaddr.
Порт задаётся в конфигурационном файле параметром \b gateway_port или
параметром командной строки \b --xxx-gateway-port. По умолчанию используется порт \b 502.
\b --xxx-recv-timeout или \b recv_timeout msec - таймаут на приём одного сообщения. По умолчанию 100 мсек.
\b --xxx-timeout или \b timeout msec - таймаут на определение отсутствия связи
(после этого идёт попытка реинициализировать соединение)
По умолчанию 5000 мсек.
\b --xxx-reinit-timeout или \b reinit_timeout msec - таймаут на реинициализацию канала связи (после потери связи)
По умолчанию timeout мсек.
\b --xxx-no-query-optimization или \b no_query_optimization - [1|0] отключить оптимизацию запросов
Оптимизация заключается в том, что регистры идущие подряд автоматически запрашиваются/записываются одним запросом.
В связи с чем, функция указанная в качестве \b mbfunc игнорируется и подменяется на работающую с многими регистрами.
\b --xxx-polltime или \b polltime msec - пауза между опросами. По умолчанию 100 мсек.
\b --xxx-checktime или \b checktime msec - пауза между проверками связи по разным каналам. По умолчанию 5000 мсек.
Если задать <=0, то каналы будут просто переключаться по кругу (по timeout-у) в соответсвии с приоритетом (см. <GateList>).
Если >0, то происходит проверка связи (раз в checktime) по всем каналам (см. <GateList>) и в случае потери связи,
происходит переключение на следующий канал, по которому связь есть.
\b --xxx-initPause или \b initPause msec - пауза перед началом работы, после активации. По умолчанию 50 мсек.
\b --xxx-force или \b force [1|0]
- 1 - перечитывать значения входов из SharedMemory на каждом цикле
- 0 - обновлять значения только по изменению
\b --xxx-persistent-connection или \b persistent_connection - НЕ закрывать соединение после каждого запроса.
\b --xxx-force-out или \b force_out [1|0]
- 1 - перечитывать значения выходов из SharedMemory на каждом цикле
- 0 - обновлять значения только по изменению
\b --xxx-reg-from-id или \b reg_from_id [1|0]
- 1 - в качестве регистра использовать идентификатор датчика
- 0 - регистр брать из поля tcp_mbreg
\b --xxx-heartbeat-id или \b heartbeat_id ID - идентификатор датчика "сердцебиения" (см. \ref sec_SM_HeartBeat)
\b --xxx-heartbeat-max или \b heartbeat_max val - сохраняемое значение счётчика "сердцебиения".
\b --xxx-activate-timeout msec . По умолчанию 2000. - время ожидания готовности SharedMemory к работе.
\b --xxx-check-func [1,2,3,4] - Номер функции для проверки соединения
\b --xxx-check-addr [1..255 ] - Адрес устройства для проверки соединения
\b --xxx-check-reg [1..65535] - Регистр для проверки соединения
\b --xxx-check-init-from-regmap - Взять адрес, функцию и регистр для проверки связи из списка опроса
\section sec_MBTCPM_ConfList Конфигурирование списка регистров для ModbusTCP master
Конфигурационные параметры задаются в секции <sensors> конфигурационного файла.
Список обрабатываемых регистров задаётся при помощи двух параметров командной строки
\b --xxx-filter-field - задаёт фильтрующее поле для датчиков
\b --xxx-filter-value - задаёт значение фильтрующего поля. Необязательный параметр.
\b --xxx-statistic-sec sec - при наличии выведет кол-во посланных запросов за этот промежуток времени.
\b --xxx-set-prop-prefix [str] - Использовать 'str' в качестве префикса для свойств.
Если не указать 'str' будет использован пустой префикс.
Если параметры не заданы, будет произведена попытка загрузить все датчики, у которых
присутствуют необходимые настроечные параметры.
\warning Если в результате список будет пустым, процесс завершает работу.
Пример конфигурационных параметров:
К основным параметрам относятся следующие (префикс tcp_ - для примера):
Помимо этого можно задавать следующие параметры:
Для инициализации "выходов" (регистров которые пишутся) можно использовать поля:
Если указано tcp_preinit="1", то прежде чем начать писать регистр в устройство, будет произведено его чтение.
По умолчанию все "записываемые" регистры инициализируются значением из SM. Т.е. пока не будет первый раз считано значение из SM, регистры в устройство писатся не будут. Чтобы отключить это поведение, можно указать параметр
При этом будет записывыться значение "default".
\section sec_MBTCPM_ExchangeMode Управление режимом работы MBTCPMultiMaster
В MBTCPMultiMaster заложена возможность управлять режимом работы процесса. Поддерживаются
следующие режимы:
- \b emNone - нормальная работа (по умолчанию)
- \b emWriteOnly - "только посылка данных" (работают только write-функции)
- \b emReadOnly - "только чтение" (работают только read-функции)
- \b emSkipSaveToSM - "не записывать данные в SM", это особый режим, похожий на \b emWriteOnly,
но отличие в том, что при этом режиме ведётся полноценый обмен (и read и write),
только реально данные не записываются в SharedMemory(SM).
- \b emSkipExchnage - отключить обмен (при этом данные "из SM" обновляются).
Режимы переключаются при помощи датчика, который можно задать либо аргументом командной строки
\b --prefix-exchange-mode-id либо в конф. файле параметром \b exchangeModeID="". Константы определяющие режимы объявлены в MBTCPMultiMaster::ExchangeMode.
\section sec_MBTCPM_CheckConnection Проверка соединения
Для контроля состояния связи по "резервным" каналам создаётся специальный поток (check_thread), в котором
происходит периодическая проверка связи по всем "пассивным"(резервным) в данный момент каналам. Это используется
как для общей диагностики в системе, так и при выборе на какой канал переключаться в случае пропажи связи в основном канале.
Т.е. будет выбран ближайший приоритетный канал у которого выставлен признак что есть связь.
Период проверки связи по "резервным" каналам задаётся при помощи --prefix-checktime или параметром checktime="" в конфигурационном файле.
В MBTCPMultiMaster реализовано два механизма проверки связи.
- По умолчанию используется простая установка соединения и тут же его разрыв. Т.е. данные никакие не посылаются,
но проверяется что host и port доступны для подключения.
- Второй способ: это проверка соединения с посылкой modbus-запроса. Для этого имеется два способа
указать адрес устройства, регистр и функция опроса для проверки.
Либо в секции <GateList> для каждого канала можно указать:
- адрес устройства \b checkAddr=""
- функцию проверки \b checkFunc="" - функция может быть только [01,02,03,04] (т.е. функции чтения).
- регистр \b checkReg
Либо в командной строке \b задать параметры --prefix-check-addr, --prefix-check-func, --prefix-check-reg,
которые будут одинаковыми для \b ВСЕХ \b КАНАЛОВ.
Помимо этого если указать в командной строке аргумент --prefix-check-init-from-regmap, то для тестирования
соединения будет взят первый попавшийся регистр из списка обмена.
\warning Способ проверки при помощи "modbus-запроса" имеет ряд проблем: Если фактически производится
обмен с несколькими устройствами (несколько mbaddr) через TCP-шлюз, то может быть "ложное" срабатывание,
т.к. фактически состояние канала будет определяться только под связи с каким-то одним конкретным устройством.
И получается, что если обмен ведётся например с тремя устройствами, но
проверка канала происходит только по связи с первым, то если оно перестанет отвечать, это будет считаться
сбоем всего канала и этот канал будет исключён из обмена (!). Если ведётся обмен только с одним устройством,
такой проблемы не возникает.
Но к плюсам данного способа проверки связи ("modbus-запросом") является то, что соедиенение поддерживается
постоянным, в отличие от "первого способа" при котором оно создаётся и сразу рвётся и если проверка
настроена достаточно часто ( < TIME_WAIT для сокетов), то при длительной работе могут закончится дескрипторы
на создание сокетов.
|
overrideprotectedvirtual |
Деактивация объекта (переопределяется для необходимых действий при завершении работы)
Переопределяет метод предка uniset::MBExchange.
|
static |
глобальная функция для инициализации объекта
1.8.15