Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
U
uniset2
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
UniSet project repositories
uniset2
Commits
df497744
You need to sign in or sign up before continuing.
Commit
df497744
authored
Oct 31, 2011
by
Pavel Vainerman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(Modbus): продолжаю выносить код в базовый класс
parent
a15d2cc4
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
127 additions
and
3794 deletions
+127
-3794
configure.ac
configure.ac
+1
-0
Makefile.am
extensions/MBTCPMaster/Makefile.am
+4
-2
start_fg.sh
extensions/MBTCPMaster/start_fg.sh
+1
-1
MBExchange.cc
extensions/ModbusMaster/MBExchange.cc
+100
-538
RTUStorage.cc
extensions/ModbusMaster/RTUStorage.cc
+11
-89
RTUStorage.h
extensions/ModbusMaster/RTUStorage.h
+1
-3
Makefile.am
extensions/RTUExchange/Makefile.am
+9
-5
RTUStorage.cc
extensions/RTUExchange/RTUStorage.cc
+0
-525
RTUStorage.h
extensions/RTUExchange/RTUStorage.h
+0
-79
MBExchange.cc
extensions/lib/MBExchange.cc
+0
-2552
No files found.
configure.ac
View file @
df497744
...
@@ -181,6 +181,7 @@ AC_CONFIG_FILES([Makefile
...
@@ -181,6 +181,7 @@ AC_CONFIG_FILES([Makefile
extensions/IOControl/libUniSetIOControl.pc
extensions/IOControl/libUniSetIOControl.pc
extensions/RTUExchange/Makefile
extensions/RTUExchange/Makefile
extensions/RTUExchange/libUniSetRTU.pc
extensions/RTUExchange/libUniSetRTU.pc
extensions/ModbusMaster/Makefile
extensions/ModbusSlave/Makefile
extensions/ModbusSlave/Makefile
extensions/ModbusSlave/libUniSetMBSlave.pc
extensions/ModbusSlave/libUniSetMBSlave.pc
extensions/MBTCPMaster/Makefile
extensions/MBTCPMaster/Makefile
...
...
extensions/MBTCPMaster/Makefile.am
View file @
df497744
...
@@ -8,16 +8,18 @@ libUniSetMBTCPMaster_la_LDFLAGS = -version-info $(UMBTCP_VER)
...
@@ -8,16 +8,18 @@ libUniSetMBTCPMaster_la_LDFLAGS = -version-info $(UMBTCP_VER)
libUniSetMBTCPMaster_la_LIBADD
=
$(top_builddir)
/lib/libUniSet.la
\
libUniSetMBTCPMaster_la_LIBADD
=
$(top_builddir)
/lib/libUniSet.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(top_builddir)
/extensions/ModbusMaster/libMBMaster.la
\
$(SIGC_LIBS)
$(SIGC_LIBS)
libUniSetMBTCPMaster_la_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
$(SIGC_CFLAGS)
libUniSetMBTCPMaster_la_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
-I
$(top_builddir)
/extensions/ModbusMaster
$(SIGC_CFLAGS)
libUniSetMBTCPMaster_la_SOURCES
=
MBTCPMaster.cc
libUniSetMBTCPMaster_la_SOURCES
=
MBTCPMaster.cc
@PACKAGE@
_mbtcpmaster_SOURCES
=
main.cc
@PACKAGE@
_mbtcpmaster_SOURCES
=
main.cc
@PACKAGE@
_mbtcpmaster_LDADD
=
libUniSetMBTCPMaster.la
$(top_builddir)
/lib/libUniSet.la
\
@PACKAGE@
_mbtcpmaster_LDADD
=
libUniSetMBTCPMaster.la
$(top_builddir)
/lib/libUniSet.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(top_builddir)
/extensions/ModbusMaster/libMBMaster.la
\
$(SIGC_LIBS)
$(SIGC_LIBS)
@PACKAGE@
_mbtcpmaster_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
$(SIGC_CFLAGS)
@PACKAGE@
_mbtcpmaster_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
-I
$(top_builddir)
/extensions/ModbusMaster
$(SIGC_CFLAGS)
# install
# install
devel_include_HEADERS
=
*
.h
devel_include_HEADERS
=
*
.h
...
...
extensions/MBTCPMaster/start_fg.sh
View file @
df497744
#!/bin/sh
#!/bin/sh
./uniset-start.sh
-
g
./uniset-mbtcpmaster
\
./uniset-start.sh
-
f
./uniset-mbtcpmaster
\
--confile
test.xml
\
--confile
test.xml
\
--mbtcp-name
MBMaster1
\
--mbtcp-name
MBMaster1
\
--smemory-id
SharedMemory
\
--smemory-id
SharedMemory
\
...
...
extensions/ModbusMaster/MBExchange.cc
View file @
df497744
...
@@ -3,7 +3,6 @@
...
@@ -3,7 +3,6 @@
#include <limits>
#include <limits>
#include <sstream>
#include <sstream>
#include <Exceptions.h>
#include <Exceptions.h>
#include <UniSetTypes.h>
#include <extensions/Extensions.h>
#include <extensions/Extensions.h>
#include "MBExchange.h"
#include "MBExchange.h"
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
...
@@ -21,7 +20,6 @@ force(false),
...
@@ -21,7 +20,6 @@ force(false),
force_out
(
false
),
force_out
(
false
),
mbregFromID
(
false
),
mbregFromID
(
false
),
sidExchangeMode
(
DefaultObjectId
),
sidExchangeMode
(
DefaultObjectId
),
exchangeMode
(
emNone
),
activated
(
false
),
activated
(
false
),
noQueryOptimization
(
false
),
noQueryOptimization
(
false
),
no_extimer
(
false
),
no_extimer
(
false
),
...
@@ -57,19 +55,10 @@ pollActivated(false)
...
@@ -57,19 +55,10 @@ pollActivated(false)
if
(
stat_time
>
0
)
if
(
stat_time
>
0
)
ptStatistic
.
setTiming
(
stat_time
*
1000
);
ptStatistic
.
setTiming
(
stat_time
*
1000
);
recv_timeout
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-recv-timeout"
,
it
.
getProp
(
"recv_timeout"
),
500
);
// recv_timeout = conf->getArgPInt("--" + prefix + "-recv-timeout",it.getProp("recv_timeout"), 500);
//
int
tout
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-timeout"
,
it
.
getProp
(
"timeout"
),
5000
);
// int tout = conf->getArgPInt("--" + prefix + "-timeout",it.getProp("timeout"), 5000);
// для совместимости со старым RTUExchange
// ptTimeout.setTiming(tout);
// надо обратывать и all-timeout
tout
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-all-timeout"
,
it
.
getProp
(
"all_timeout"
),
tout
);
ptTimeout
.
setTiming
(
tout
);
tout
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-reopen-timeout"
,
it
.
getProp
(
"reopen_timeout"
),
10000
);
ptReopen
.
setTiming
(
tout
);
aftersend_pause
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-aftersend-pause"
,
it
.
getProp
(
"aftersend_pause"
),
0
);
noQueryOptimization
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-no-query-optimization"
,
it
.
getProp
(
"no_query_optimization"
));
noQueryOptimization
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-no-query-optimization"
,
it
.
getProp
(
"no_query_optimization"
));
...
@@ -80,7 +69,7 @@ pollActivated(false)
...
@@ -80,7 +69,7 @@ pollActivated(false)
initPause
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-initPause"
,
it
.
getProp
(
"initPause"
),
3000
);
initPause
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-initPause"
,
it
.
getProp
(
"initPause"
),
3000
);
sleepPause_usec
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-sleepPause-usec"
,
it
.
getProp
(
"sle
ep
Pause"
),
100
);
sleepPause_usec
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-sleepPause-usec"
,
it
.
getProp
(
"sle
pe
Pause"
),
100
);
force
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-force"
,
it
.
getProp
(
"force"
));
force
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-force"
,
it
.
getProp
(
"force"
));
force_out
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-force-out"
,
it
.
getProp
(
"force_out"
));
force_out
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-force-out"
,
it
.
getProp
(
"force_out"
));
...
@@ -99,7 +88,7 @@ pollActivated(false)
...
@@ -99,7 +88,7 @@ pollActivated(false)
throw
SystemError
(
err
.
str
());
throw
SystemError
(
err
.
str
());
}
}
int
heartbeatTime
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-heartbeat-time"
,
it
.
getProp
(
"heartbeatTime"
),
conf
->
getHeartBeatTime
()
);
int
heartbeatTime
=
getHeartBeatTime
(
);
if
(
heartbeatTime
)
if
(
heartbeatTime
)
ptHeartBeat
.
setTiming
(
heartbeatTime
);
ptHeartBeat
.
setTiming
(
heartbeatTime
);
else
else
...
@@ -143,9 +132,6 @@ void MBExchange::help_print( int argc, const char* const* argv )
...
@@ -143,9 +132,6 @@ void MBExchange::help_print( int argc, const char* const* argv )
cout
<<
"--prefix-name name - ObjectId (имя) процесса. По умолчанию: MBExchange1"
<<
endl
;
cout
<<
"--prefix-name name - ObjectId (имя) процесса. По умолчанию: MBExchange1"
<<
endl
;
cout
<<
"--prefix-confnode name - Настроечная секция в конф. файле <name>. "
<<
endl
;
cout
<<
"--prefix-confnode name - Настроечная секция в конф. файле <name>. "
<<
endl
;
cout
<<
"--prefix-polltime msec - Пауза между опросаом карт. По умолчанию 200 мсек."
<<
endl
;
cout
<<
"--prefix-polltime msec - Пауза между опросаом карт. По умолчанию 200 мсек."
<<
endl
;
cout
<<
"--prefix-recv-timeout msec - Таймаут на приём одного сообщения"
<<
endl
;
cout
<<
"--prefix-timeout msec - Таймаут для определения отсутствия соединения"
<<
endl
;
cout
<<
"--prefix-reopen-timeout msec - Таймаут для 'переоткрытия соединения' при отсутсвия соединения msec милисекунд. По умолчанию 10 сек."
<<
endl
;
cout
<<
"--prefix-heartbeat-id name - Данный процесс связан с указанным аналоговым heartbeat-дачиком."
<<
endl
;
cout
<<
"--prefix-heartbeat-id name - Данный процесс связан с указанным аналоговым heartbeat-дачиком."
<<
endl
;
cout
<<
"--prefix-heartbeat-max val - Максимальное значение heartbeat-счётчика для данного процесса. По умолчанию 10."
<<
endl
;
cout
<<
"--prefix-heartbeat-max val - Максимальное значение heartbeat-счётчика для данного процесса. По умолчанию 10."
<<
endl
;
cout
<<
"--prefix-ready-timeout msec - Время ожидания готовности SM к работе, мсек. (-1 - ждать 'вечно')"
<<
endl
;
cout
<<
"--prefix-ready-timeout msec - Время ожидания готовности SM к работе, мсек. (-1 - ждать 'вечно')"
<<
endl
;
...
@@ -158,27 +144,10 @@ void MBExchange::help_print( int argc, const char* const* argv )
...
@@ -158,27 +144,10 @@ void MBExchange::help_print( int argc, const char* const* argv )
cout
<<
"--prefix-filter-value val - Считывать список опрашиваемых датчиков, только у которых field=value"
<<
endl
;
cout
<<
"--prefix-filter-value val - Считывать список опрашиваемых датчиков, только у которых field=value"
<<
endl
;
cout
<<
"--prefix-statistic-sec sec - Выводить статистику опроса каждые sec секунд"
<<
endl
;
cout
<<
"--prefix-statistic-sec sec - Выводить статистику опроса каждые sec секунд"
<<
endl
;
cout
<<
"--prefix-sm-ready-timeout - время на ожидание старта SM"
<<
endl
;
cout
<<
"--prefix-sm-ready-timeout - время на ожидание старта SM"
<<
endl
;
cout
<<
"--prefix-exchange-mode-id - Идентификатор (AI) датчика, позволяющего управлять работой процесса"
<<
endl
;
cout
<<
"--prefix-set-prop-prefix val - Использовать для свойств указанный или пустой префикс."
<<
endl
;
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
MBExchange
::~
MBExchange
()
MBExchange
::~
MBExchange
()
{
{
for
(
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
if
(
it1
->
second
->
rtu
)
{
delete
it1
->
second
->
rtu
;
it1
->
second
->
rtu
=
0
;
}
RTUDevice
*
d
(
it1
->
second
);
for
(
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
delete
it
->
second
;
delete
it1
->
second
;
}
delete
shm
;
delete
shm
;
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
...
@@ -205,8 +174,6 @@ void MBExchange::step()
...
@@ -205,8 +174,6 @@ void MBExchange::step()
if
(
!
checkProcActive
()
)
if
(
!
checkProcActive
()
)
return
;
return
;
updateRespondSensors
();
if
(
sidHeartBeat
!=
DefaultObjectId
&&
ptHeartBeat
.
checkTime
()
)
if
(
sidHeartBeat
!=
DefaultObjectId
&&
ptHeartBeat
.
checkTime
()
)
{
{
try
try
...
@@ -237,7 +204,7 @@ void MBExchange::setProcActive( bool st )
...
@@ -237,7 +204,7 @@ void MBExchange::setProcActive( bool st )
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void
MBExchange
::
sigterm
(
int
signo
)
void
MBExchange
::
sigterm
(
int
signo
)
{
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
": ********* SIGTERM("
<<
signo
<<
") ********"
<<
endl
;
dlog
[
Debug
::
WARN
]
<<
myname
<<
": ********* SIGTERM("
<<
signo
<<
") ********"
<<
endl
;
setProcActive
(
false
);
setProcActive
(
false
);
UniSetObject_LT
::
sigterm
(
signo
);
UniSetObject_LT
::
sigterm
(
signo
);
}
}
...
@@ -277,7 +244,7 @@ bool MBExchange::readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec )
...
@@ -277,7 +244,7 @@ bool MBExchange::readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec )
}
}
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
MBExchange
::
DeviceType
MBExchange
::
getDeviceType
(
const
std
::
string
&
dtype
)
MBExchange
::
DeviceType
MBExchange
::
getDeviceType
(
const
std
::
string
dtype
)
{
{
if
(
dtype
.
empty
()
)
if
(
dtype
.
empty
()
)
return
dtUnknown
;
return
dtUnknown
;
...
@@ -288,9 +255,6 @@ MBExchange::DeviceType MBExchange::getDeviceType( const std::string& dtype )
...
@@ -288,9 +255,6 @@ MBExchange::DeviceType MBExchange::getDeviceType( const std::string& dtype )
if
(
dtype
==
"rtu"
||
dtype
==
"RTU"
)
if
(
dtype
==
"rtu"
||
dtype
==
"RTU"
)
return
dtRTU
;
return
dtRTU
;
if
(
dtype
==
"rtu188"
||
dtype
==
"RTU188"
)
return
dtRTU188
;
return
dtUnknown
;
return
dtUnknown
;
}
}
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
...
@@ -302,40 +266,20 @@ void MBExchange::initIterators()
...
@@ -302,40 +266,20 @@ void MBExchange::initIterators()
{
{
RTUDevice
*
d
(
it1
->
second
);
RTUDevice
*
d
(
it1
->
second
);
shm
->
initDIterator
(
d
->
resp_dit
);
shm
->
initDIterator
(
d
->
resp_dit
);
shm
->
initAIterator
(
d
->
mode_ait
);
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
{
for
(
PList
::
iterator
it2
=
it
->
second
->
slst
.
begin
();
it2
!=
it
->
second
->
slst
.
end
();
++
it2
)
for
(
PList
::
iterator
it2
=
it
->
second
->
slst
.
begin
();
it2
!=
it
->
second
->
slst
.
end
();
++
it2
)
{
{
shm
->
initDIterator
(
it2
->
dit
);
shm
->
initDIterator
(
it2
->
dit
);
shm
->
initAIterator
(
it2
->
ait
);
shm
->
initAIterator
(
it2
->
ait
);
shm
->
initAIterator
(
it2
->
t_ait
);
}
}
}
}
}
}
for
(
ThresholdList
::
iterator
t
=
thrlist
.
begin
();
t
!=
thrlist
.
end
();
++
t
)
{
shm
->
initDIterator
(
t
->
dit
);
shm
->
initAIterator
(
t
->
ait
);
shm
->
initAIterator
(
t
->
t_ait
);
}
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
bool
MBExchange
::
checkUpdateSM
(
bool
wrFunc
,
long
mdev
)
bool
MBExchange
::
checkUpdateSM
(
bool
wrFunc
)
{
{
if
(
exchangeMode
==
emSkipExchange
||
mdev
==
emSkipExchange
)
if
(
wrFunc
&&
exchangeMode
==
emReadOnly
)
{
if
(
wrFunc
)
return
true
;
// данные для посылки, должны обновляться всегда (чтобы быть актуальными)
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
"(checkUpdateSM):"
<<
" skip... mode='emSkipExchange' "
<<
endl
;
return
false
;
}
if
(
wrFunc
&&
(
exchangeMode
==
emReadOnly
||
mdev
==
emReadOnly
)
)
{
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
"(checkUpdateSM):"
dlog
[
Debug
::
LEVEL3
]
<<
"(checkUpdateSM):"
...
@@ -343,7 +287,7 @@ bool MBExchange::checkUpdateSM( bool wrFunc, long mdev )
...
@@ -343,7 +287,7 @@ bool MBExchange::checkUpdateSM( bool wrFunc, long mdev )
return
false
;
return
false
;
}
}
if
(
!
wrFunc
&&
(
exchangeMode
==
emWriteOnly
||
mdev
==
emWriteOnly
)
)
if
(
!
wrFunc
&&
exchangeMode
==
emWriteOnly
)
{
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
"(checkUpdateSM):"
dlog
[
Debug
::
LEVEL3
]
<<
"(checkUpdateSM):"
...
@@ -351,7 +295,7 @@ bool MBExchange::checkUpdateSM( bool wrFunc, long mdev )
...
@@ -351,7 +295,7 @@ bool MBExchange::checkUpdateSM( bool wrFunc, long mdev )
return
false
;
return
false
;
}
}
if
(
wrFunc
&&
(
exchangeMode
==
emSkipSaveToSM
||
mdev
==
emSkipSaveToSM
)
)
if
(
wrFunc
&&
exchangeMode
==
emSkipSaveToSM
)
{
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
"(checkUpdateSM):"
dlog
[
Debug
::
LEVEL3
]
<<
"(checkUpdateSM):"
...
@@ -437,11 +381,6 @@ std::ostream& operator<<( std::ostream& os, MBExchange::RTUDevice& d )
...
@@ -437,11 +381,6 @@ std::ostream& operator<<( std::ostream& os, MBExchange::RTUDevice& d )
return
os
;
return
os
;
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
MBExchange
::
RegInfo
*
r
)
{
return
os
<<
(
*
r
);
}
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
MBExchange
::
RegInfo
&
r
)
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
MBExchange
::
RegInfo
&
r
)
{
{
os
<<
" id="
<<
r
.
id
os
<<
" id="
<<
r
.
id
...
@@ -669,7 +608,7 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty
...
@@ -669,7 +608,7 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty
if
(
p
->
nbit
>=
0
)
if
(
p
->
nbit
>=
0
)
{
{
bool
set
=
b
[
p
->
nbit
];
bool
set
=
b
[
p
->
nbit
];
IOBase
::
processingAsDI
(
p
,
set
,
shm
,
tru
e
);
IOBase
::
processingAsDI
(
p
,
set
,
shm
,
forc
e
);
return
true
;
return
true
;
}
}
...
@@ -678,10 +617,10 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty
...
@@ -678,10 +617,10 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
{
IOBase
::
processingAsDI
(
p
,
data
[
0
],
shm
,
tru
e
);
IOBase
::
processingAsDI
(
p
,
data
[
0
],
shm
,
forc
e
);
}
}
else
else
IOBase
::
processingAsAI
(
p
,
(
signed
short
)(
data
[
0
]),
shm
,
tru
e
);
IOBase
::
processingAsAI
(
p
,
(
signed
short
)(
data
[
0
]),
shm
,
forc
e
);
return
true
;
return
true
;
}
}
...
@@ -696,10 +635,10 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty
...
@@ -696,10 +635,10 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
{
IOBase
::
processingAsDI
(
p
,
data
[
0
],
shm
,
tru
e
);
IOBase
::
processingAsDI
(
p
,
data
[
0
],
shm
,
forc
e
);
}
}
else
else
IOBase
::
processingAsAI
(
p
,
(
signed
short
)(
data
[
0
]),
shm
,
tru
e
);
IOBase
::
processingAsAI
(
p
,
(
signed
short
)(
data
[
0
]),
shm
,
forc
e
);
return
true
;
return
true
;
}
}
...
@@ -708,10 +647,10 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty
...
@@ -708,10 +647,10 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
{
IOBase
::
processingAsDI
(
p
,
data
[
0
],
shm
,
tru
e
);
IOBase
::
processingAsDI
(
p
,
data
[
0
],
shm
,
forc
e
);
}
}
else
else
IOBase
::
processingAsAI
(
p
,
(
unsigned
short
)
data
[
0
],
shm
,
tru
e
);
IOBase
::
processingAsAI
(
p
,
(
unsigned
short
)
data
[
0
],
shm
,
forc
e
);
return
true
;
return
true
;
}
}
...
@@ -725,43 +664,28 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty
...
@@ -725,43 +664,28 @@ bool MBExchange::initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty
}
}
VTypes
::
Byte
b
(
data
[
0
]);
VTypes
::
Byte
b
(
data
[
0
]);
IOBase
::
processingAsAI
(
p
,
b
.
raw
.
b
[
p
->
nbyte
-
1
],
shm
,
tru
e
);
IOBase
::
processingAsAI
(
p
,
b
.
raw
.
b
[
p
->
nbyte
-
1
],
shm
,
forc
e
);
return
true
;
return
true
;
}
}
else
if
(
p
->
vType
==
VTypes
::
vtF2
)
else
if
(
p
->
vType
==
VTypes
::
vtF2
)
{
{
VTypes
::
F2
f
(
data
,
VTypes
::
F2
::
wsize
());
VTypes
::
F2
f
(
data
,
VTypes
::
F2
::
wsize
());
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
true
);
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
force
);
}
else
if
(
p
->
vType
==
VTypes
::
vtF2r
)
{
VTypes
::
F2r
f
(
data
,
VTypes
::
F2r
::
wsize
());
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
true
);
}
}
else
if
(
p
->
vType
==
VTypes
::
vtF4
)
else
if
(
p
->
vType
==
VTypes
::
vtF4
)
{
{
VTypes
::
F4
f
(
data
,
VTypes
::
F4
::
wsize
());
VTypes
::
F4
f
(
data
,
VTypes
::
F4
::
wsize
());
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
tru
e
);
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
forc
e
);
}
}
else
if
(
p
->
vType
==
VTypes
::
vtI2
)
else
if
(
p
->
vType
==
VTypes
::
vtI2
)
{
{
VTypes
::
I2
i2
(
data
,
VTypes
::
I2
::
wsize
());
VTypes
::
I2
i2
(
data
,
VTypes
::
I2
::
wsize
());
IOBase
::
processingAsAI
(
p
,
(
int
)
i2
,
shm
,
true
);
IOBase
::
processingAsAI
(
p
,
(
int
)
i2
,
shm
,
force
);
}
else
if
(
p
->
vType
==
VTypes
::
vtI2r
)
{
VTypes
::
I2r
i2
(
data
,
VTypes
::
I2
::
wsize
());
IOBase
::
processingAsAI
(
p
,
(
int
)
i2
,
shm
,
true
);
}
}
else
if
(
p
->
vType
==
VTypes
::
vtU2
)
else
if
(
p
->
vType
==
VTypes
::
vtU2
)
{
{
VTypes
::
U2
u2
(
data
,
VTypes
::
U2
::
wsize
());
VTypes
::
U2
u2
(
data
,
VTypes
::
U2
::
wsize
());
IOBase
::
processingAsAI
(
p
,
(
unsigned
int
)
u2
,
shm
,
true
);
IOBase
::
processingAsAI
(
p
,
(
unsigned
int
)
u2
,
shm
,
force
);
}
else
if
(
p
->
vType
==
VTypes
::
vtU2r
)
{
VTypes
::
U2r
u2
(
data
,
VTypes
::
U2
::
wsize
());
IOBase
::
processingAsAI
(
p
,
(
unsigned
int
)
u2
,
shm
,
true
);
}
}
return
true
;
return
true
;
...
@@ -799,15 +723,6 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
...
@@ -799,15 +723,6 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
{
{
RegInfo
*
p
(
it
->
second
);
RegInfo
*
p
(
it
->
second
);
if
(
dev
->
mode
==
emSkipExchange
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(pollRTU): SKIP EXCHANGE (mode=emSkipExchange) "
<<
" mbaddr="
<<
ModbusRTU
::
addr2str
(
dev
->
mbaddr
)
<<
endl
;
return
true
;
}
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
{
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(pollRTU): poll "
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(pollRTU): poll "
...
@@ -854,7 +769,7 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
...
@@ -854,7 +769,7 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
case
ModbusRTU
:
:
fnReadOutputRegisters
:
case
ModbusRTU
:
:
fnReadOutputRegisters
:
{
{
ModbusRTU
::
ReadOutputRetMessage
ret
=
mb
->
read03
(
dev
->
mbaddr
,
p
->
mbreg
,
p
->
q_count
);
ModbusRTU
::
ReadOutputRetMessage
ret
=
mb
->
read03
(
dev
->
mbaddr
,
p
->
mbreg
,
p
->
q_count
);
for
(
int
i
=
0
;
i
<
p
->
q_count
;
i
++
,
it
++
)
for
(
int
i
=
0
;
i
<
p
->
q_count
;
i
++
,
it
++
)
it
->
second
->
mbval
=
ret
.
data
[
i
];
it
->
second
->
mbval
=
ret
.
data
[
i
];
it
--
;
it
--
;
...
@@ -1008,40 +923,6 @@ void MBExchange::updateSM()
...
@@ -1008,40 +923,6 @@ void MBExchange::updateSM()
{
{
RTUDevice
*
d
(
it1
->
second
);
RTUDevice
*
d
(
it1
->
second
);
if
(
d
->
mode_id
!=
DefaultObjectId
)
{
try
{
if
(
!
shm
->
isLocalwork
()
)
d
->
mode
=
shm
->
localGetValue
(
d
->
mode_ait
,
d
->
mode_id
);
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
catch
(
IOController_i
::
IOBadParam
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM):(IOBadParam) "
<<
ex
.
err
<<
endl
;
}
catch
(
IONotifyController_i
::
BadRange
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM): (BadRange)..."
<<
endl
;
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM): "
<<
ex
<<
endl
;
}
catch
(
CORBA
::
SystemException
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM): CORBA::SystemException: "
<<
ex
.
NP_minorString
()
<<
endl
;
}
catch
(...)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM): check modeSensor..catch ..."
<<
endl
;
}
}
// обновление датчиков связи происходит в другом потоке
// обновление датчиков связи происходит в другом потоке
// чтобы не зависеть от TCP таймаутов
// чтобы не зависеть от TCP таймаутов
// см. updateRespondSensors()
// см. updateRespondSensors()
...
@@ -1055,8 +936,6 @@ void MBExchange::updateSM()
...
@@ -1055,8 +936,6 @@ void MBExchange::updateSM()
updateRTU
(
it
);
updateRTU
(
it
);
else
if
(
d
->
dtype
==
dtMTR
)
else
if
(
d
->
dtype
==
dtMTR
)
updateMTR
(
it
);
updateMTR
(
it
);
else
if
(
d
->
dtype
==
dtRTU188
)
updateRTU188
(
it
);
}
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
{
...
@@ -1109,7 +988,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
...
@@ -1109,7 +988,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
if
(
!
save
&&
write_only
)
if
(
!
save
&&
write_only
)
return
;
return
;
if
(
!
checkUpdateSM
(
save
,
r
->
dev
->
mode
)
)
if
(
!
checkUpdateSM
(
save
)
)
return
;
return
;
// если требуется инициализация и она ещё не произведена,
// если требуется инициализация и она ещё не произведена,
...
@@ -1118,7 +997,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
...
@@ -1118,7 +997,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
return
;
return
;
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateP): sid="
<<
p
->
si
.
id
dlog
[
Debug
::
LEVEL3
]
<<
"updateP: sid="
<<
p
->
si
.
id
<<
" mbval="
<<
r
->
mbval
<<
" mbval="
<<
r
->
mbval
<<
" vtype="
<<
p
->
vType
<<
" vtype="
<<
p
->
vType
<<
" rnum="
<<
p
->
rnum
<<
" rnum="
<<
p
->
rnum
...
@@ -1280,7 +1159,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
...
@@ -1280,7 +1159,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
return
;
return
;
}
}
else
if
(
p
->
vType
==
VTypes
::
vtF2
||
p
->
vType
==
VTypes
::
vtF2r
)
else
if
(
p
->
vType
==
VTypes
::
vtF2
)
{
{
RegMap
::
iterator
i
(
p
->
reg
->
rit
);
RegMap
::
iterator
i
(
p
->
reg
->
rit
);
if
(
save
)
if
(
save
)
...
@@ -1288,18 +1167,9 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
...
@@ -1288,18 +1167,9 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
if
(
r
->
mb_initOK
)
if
(
r
->
mb_initOK
)
{
{
float
f
=
IOBase
::
processingFasAO
(
p
,
shm
,
force_out
);
float
f
=
IOBase
::
processingFasAO
(
p
,
shm
,
force_out
);
if
(
p
->
vType
==
VTypes
::
vtF2
)
{
VTypes
::
F2
f2
(
f
);
VTypes
::
F2
f2
(
f
);
for
(
int
k
=
0
;
k
<
VTypes
::
F2
::
wsize
();
k
++
,
i
++
)
for
(
int
k
=
0
;
k
<
VTypes
::
F2
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
f2
.
raw
.
v
[
k
];
i
->
second
->
mbval
=
f2
.
raw
.
v
[
k
];
}
else
if
(
p
->
vType
==
VTypes
::
vtF2r
)
{
VTypes
::
F2r
f2
(
f
);
for
(
int
k
=
0
;
k
<
VTypes
::
F2r
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
f2
.
raw
.
v
[
k
];
}
r
->
sm_initOK
=
true
;
r
->
sm_initOK
=
true
;
}
}
...
@@ -1310,21 +1180,10 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
...
@@ -1310,21 +1180,10 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
for
(
int
k
=
0
;
k
<
VTypes
::
F2
::
wsize
();
k
++
,
i
++
)
for
(
int
k
=
0
;
k
<
VTypes
::
F2
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
data
[
k
]
=
i
->
second
->
mbval
;
float
f
=
0
;
VTypes
::
F2
f
(
data
,
VTypes
::
F2
::
wsize
());
if
(
p
->
vType
==
VTypes
::
vtF2
)
{
VTypes
::
F2
f1
(
data
,
VTypes
::
F2
::
wsize
());
f
=
(
float
)
f1
;
}
else
if
(
p
->
vType
==
VTypes
::
vtF2r
)
{
VTypes
::
F2r
f1
(
data
,
VTypes
::
F2r
::
wsize
());
f
=
(
float
)
f1
;
}
delete
[]
data
;
delete
[]
data
;
IOBase
::
processingFasAI
(
p
,
f
,
shm
,
force
);
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
force
);
}
}
}
}
else
if
(
p
->
vType
==
VTypes
::
vtF4
)
else
if
(
p
->
vType
==
VTypes
::
vtF4
)
...
@@ -1352,7 +1211,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
...
@@ -1352,7 +1211,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
force
);
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
force
);
}
}
}
}
else
if
(
p
->
vType
==
VTypes
::
vtI2
||
p
->
vType
==
VTypes
::
vtI2r
)
else
if
(
p
->
vType
==
VTypes
::
vtI2
)
{
{
RegMap
::
iterator
i
(
p
->
reg
->
rit
);
RegMap
::
iterator
i
(
p
->
reg
->
rit
);
if
(
save
)
if
(
save
)
...
@@ -1360,18 +1219,10 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
...
@@ -1360,18 +1219,10 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
if
(
r
->
mb_initOK
)
if
(
r
->
mb_initOK
)
{
{
long
v
=
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
long
v
=
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
if
(
p
->
vType
==
VTypes
::
vtI2
)
{
VTypes
::
I2
i2
(
v
);
VTypes
::
I2
i2
(
v
);
for
(
int
k
=
0
;
k
<
VTypes
::
I2
::
wsize
();
k
++
,
i
++
)
for
(
int
k
=
0
;
k
<
VTypes
::
I2
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
i2
.
raw
.
v
[
k
];
i
->
second
->
mbval
=
i2
.
raw
.
v
[
k
];
}
else
if
(
p
->
vType
==
VTypes
::
vtI2r
)
{
VTypes
::
I2r
i2
(
v
);
for
(
int
k
=
0
;
k
<
VTypes
::
I2
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
i2
.
raw
.
v
[
k
];
}
r
->
sm_initOK
=
true
;
r
->
sm_initOK
=
true
;
}
}
}
}
...
@@ -1381,23 +1232,13 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
...
@@ -1381,23 +1232,13 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
for
(
int
k
=
0
;
k
<
VTypes
::
I2
::
wsize
();
k
++
,
i
++
)
for
(
int
k
=
0
;
k
<
VTypes
::
I2
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
data
[
k
]
=
i
->
second
->
mbval
;
int
v
=
0
;
if
(
p
->
vType
==
VTypes
::
vtI2
)
{
VTypes
::
I2
i2
(
data
,
VTypes
::
I2
::
wsize
());
VTypes
::
I2
i2
(
data
,
VTypes
::
I2
::
wsize
());
v
=
(
int
)
i2
;
}
else
if
(
p
->
vType
==
VTypes
::
vtI2r
)
{
VTypes
::
I2r
i2
(
data
,
VTypes
::
I2
::
wsize
());
v
=
(
int
)
i2
;
}
delete
[]
data
;
delete
[]
data
;
IOBase
::
processingAsAI
(
p
,
v
,
shm
,
force
);
IOBase
::
processingAsAI
(
p
,
(
int
)
i2
,
shm
,
force
);
}
}
}
}
else
if
(
p
->
vType
==
VTypes
::
vtU2
||
p
->
vType
==
VTypes
::
vtU2r
)
else
if
(
p
->
vType
==
VTypes
::
vtU2
)
{
{
RegMap
::
iterator
i
(
p
->
reg
->
rit
);
RegMap
::
iterator
i
(
p
->
reg
->
rit
);
if
(
save
)
if
(
save
)
...
@@ -1405,18 +1246,9 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
...
@@ -1405,18 +1246,9 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
if
(
r
->
mb_initOK
)
if
(
r
->
mb_initOK
)
{
{
long
v
=
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
long
v
=
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
if
(
p
->
vType
==
VTypes
::
vtU2
)
{
VTypes
::
U2
u2
(
v
);
VTypes
::
U2
u2
(
v
);
for
(
int
k
=
0
;
k
<
VTypes
::
U2
::
wsize
();
k
++
,
i
++
)
for
(
int
k
=
0
;
k
<
VTypes
::
U2
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
u2
.
raw
.
v
[
k
];
i
->
second
->
mbval
=
u2
.
raw
.
v
[
k
];
}
else
if
(
p
->
vType
==
VTypes
::
vtU2r
)
{
VTypes
::
U2r
u2
(
v
);
for
(
int
k
=
0
;
k
<
VTypes
::
U2
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
u2
.
raw
.
v
[
k
];
}
r
->
sm_initOK
=
true
;
r
->
sm_initOK
=
true
;
}
}
...
@@ -1427,26 +1259,16 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
...
@@ -1427,26 +1259,16 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
for
(
int
k
=
0
;
k
<
VTypes
::
U2
::
wsize
();
k
++
,
i
++
)
for
(
int
k
=
0
;
k
<
VTypes
::
U2
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
data
[
k
]
=
i
->
second
->
mbval
;
unsigned
int
v
=
0
;
if
(
p
->
vType
==
VTypes
::
vtU2
)
{
VTypes
::
U2
u2
(
data
,
VTypes
::
U2
::
wsize
());
VTypes
::
U2
u2
(
data
,
VTypes
::
U2
::
wsize
());
v
=
(
unsigned
int
)
u2
;
}
else
if
(
p
->
vType
==
VTypes
::
vtU2r
)
{
VTypes
::
U2r
u2
(
data
,
VTypes
::
U2
::
wsize
());
v
=
(
unsigned
int
)
u2
;
}
delete
[]
data
;
delete
[]
data
;
IOBase
::
processingAsAI
(
p
,
v
,
shm
,
force
);
IOBase
::
processingAsAI
(
p
,
(
unsigned
int
)
u2
,
shm
,
force
);
}
}
}
}
return
;
return
;
}
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty):(NameNotFound) "
<<
ex
.
err
<<
endl
;
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
}
...
@@ -1480,14 +1302,32 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
...
@@ -1480,14 +1302,32 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
void
MBExchange
::
updateMTR
(
RegMap
::
iterator
&
rit
)
void
MBExchange
::
updateMTR
(
RegMap
::
iterator
&
rit
)
{
{
RegInfo
*
r
(
rit
->
second
);
RegInfo
*
r
(
rit
->
second
);
if
(
!
r
||
!
r
->
dev
)
return
;
using
namespace
ModbusRTU
;
using
namespace
ModbusRTU
;
bool
save
=
isWriteFunction
(
r
->
mbfunc
);
bool
save
=
isWriteFunction
(
r
->
mbfunc
);
if
(
!
checkUpdateSM
(
save
,
r
->
dev
->
mode
)
)
if
(
save
&&
exchangeMode
==
emReadOnly
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR):"
<<
" skip... mode=emReadOnly "
<<
endl
;
return
;
return
;
}
if
(
!
save
&&
exchangeMode
==
emWriteOnly
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR):"
<<
" skip... mode=emWriteOnly "
<<
endl
;
return
;
}
if
(
save
&&
exchangeMode
==
emSkipSaveToSM
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR):"
<<
" skip... mode=emSkipSaveToSM "
<<
endl
;
return
;
}
{
{
for
(
PList
::
iterator
it
=
r
->
slst
.
begin
();
it
!=
r
->
slst
.
end
();
++
it
)
for
(
PList
::
iterator
it
=
r
->
slst
.
begin
();
it
!=
r
->
slst
.
end
();
++
it
)
...
@@ -1707,56 +1547,22 @@ void MBExchange::updateMTR( RegMap::iterator& rit )
...
@@ -1707,56 +1547,22 @@ void MBExchange::updateMTR( RegMap::iterator& rit )
}
}
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void
MBExchange
::
updateRTU188
(
RegMap
::
iterator
&
r
it
)
void
MBExchange
::
updateRTU188
(
RegMap
::
iterator
&
it
)
{
{
RegInfo
*
r
(
r
it
->
second
);
RegInfo
*
r
(
it
->
second
);
if
(
!
r
||
!
r
->
dev
||
!
r
->
dev
->
rtu
)
if
(
!
r
->
dev
->
rtu
)
return
;
return
;
using
namespace
ModbusRTU
;
using
namespace
ModbusRTU
;
bool
save
=
isWriteFunction
(
r
->
mbfunc
);
// bool save = false;
// пока-что функции записи в обмене с RTU188
// не реализованы
if
(
isWriteFunction
(
r
->
mbfunc
)
)
if
(
isWriteFunction
(
r
->
mbfunc
)
)
{
{
// save = true;
cerr
<<
myname
<<
"(updateRTU188): write reg("
<<
dat2str
(
r
->
mbreg
)
<<
") to RTU188 NOT YET!!!"
<<
endl
;
cerr
<<
myname
<<
"(updateRTU188): write reg("
<<
dat2str
(
r
->
mbreg
)
<<
") to RTU188 NOT YET!!!"
<<
endl
;
return
;
return
;
}
}
if
(
exchangeMode
==
emSkipExchange
||
r
->
dev
->
mode
==
emSkipExchange
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188):"
<<
" skip... mode=emSkipExchange "
<<
endl
;
return
;
}
if
(
save
&&
(
exchangeMode
==
emReadOnly
||
r
->
dev
->
mode
==
emReadOnly
)
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188):"
<<
" skip... mode=emReadOnly "
<<
endl
;
return
;
}
if
(
!
save
&&
(
exchangeMode
==
emWriteOnly
||
r
->
dev
->
mode
==
emWriteOnly
)
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRTU188):"
<<
" skip... mode=emWriteOnly "
<<
endl
;
return
;
}
if
(
save
&&
(
exchangeMode
==
emSkipSaveToSM
||
r
->
dev
->
mode
==
emSkipSaveToSM
)
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRT188):"
<<
" skip... mode=emSkipSaveToSM "
<<
endl
;
return
;
}
for
(
PList
::
iterator
it
=
r
->
slst
.
begin
();
it
!=
r
->
slst
.
end
();
++
it
)
for
(
PList
::
iterator
it
=
r
->
slst
.
begin
();
it
!=
r
->
slst
.
end
();
++
it
)
{
{
try
try
...
@@ -1765,11 +1571,14 @@ void MBExchange::updateRTU188( RegMap::iterator& rit )
...
@@ -1765,11 +1571,14 @@ void MBExchange::updateRTU188( RegMap::iterator& rit )
{
{
bool
set
=
r
->
dev
->
rtu
->
getState
(
r
->
rtuJack
,
r
->
rtuChan
,
it
->
stype
);
bool
set
=
r
->
dev
->
rtu
->
getState
(
r
->
rtuJack
,
r
->
rtuChan
,
it
->
stype
);
IOBase
::
processingAsDI
(
&
(
*
it
),
set
,
shm
,
force
);
IOBase
::
processingAsDI
(
&
(
*
it
),
set
,
shm
,
force
);
continue
;
}
}
else
if
(
it
->
stype
==
UniversalIO
::
AnalogInput
)
if
(
it
->
stype
==
UniversalIO
::
AnalogInput
)
{
{
long
val
=
r
->
dev
->
rtu
->
getInt
(
r
->
rtuJack
,
r
->
rtuChan
,
it
->
stype
);
long
val
=
r
->
dev
->
rtu
->
getInt
(
r
->
rtuJack
,
r
->
rtuChan
,
it
->
stype
);
IOBase
::
processingAsAI
(
&
(
*
it
),
val
,
shm
,
force
);
IOBase
::
processingAsAI
(
&
(
*
it
),
val
,
shm
,
force
);
continue
;
}
}
}
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
catch
(
IOController_i
::
NameNotFound
&
ex
)
...
@@ -1912,15 +1721,6 @@ bool MBExchange::initRSProperty( RSProperty& p, UniXML_iterator& it )
...
@@ -1912,15 +1721,6 @@ bool MBExchange::initRSProperty( RSProperty& p, UniXML_iterator& it )
if
(
!
IOBase
::
initItem
(
&
p
,
it
,
shm
,
&
dlog
,
myname
)
)
if
(
!
IOBase
::
initItem
(
&
p
,
it
,
shm
,
&
dlog
,
myname
)
)
return
false
;
return
false
;
// проверяем не пороговый ли это датчик (т.е. не связанный с обменом)
// тогда заносим его в отдельный список
if
(
p
.
t_ai
!=
DefaultObjectId
)
{
thrlist
.
push_back
(
p
);
return
true
;
}
if
(
it
.
getIntProp
(
prop_prefix
+
"rawdata"
)
)
if
(
it
.
getIntProp
(
prop_prefix
+
"rawdata"
)
)
{
{
p
.
cal
.
minRaw
=
0
;
p
.
cal
.
minRaw
=
0
;
...
@@ -2016,21 +1816,6 @@ bool MBExchange::initRegInfo( RegInfo* r, UniXML_iterator& it, MBExchange::RTUD
...
@@ -2016,21 +1816,6 @@ bool MBExchange::initRegInfo( RegInfo* r, UniXML_iterator& it, MBExchange::RTUD
if
(
!
initMTRitem
(
it
,
r
)
)
if
(
!
initMTRitem
(
it
,
r
)
)
return
false
;
return
false
;
}
}
else
if
(
dev
->
dtype
==
MBExchange
::
dtRTU188
)
{
// only for RTU188
if
(
!
initRTU188item
(
it
,
r
)
)
return
false
;
UniversalIO
::
IOTypes
t
=
UniSetTypes
::
getIOType
(
it
.
getProp
(
"iotype"
));
r
->
mbreg
=
RTUStorage
::
getRegister
(
r
->
rtuJack
,
r
->
rtuChan
,
t
);
r
->
mbfunc
=
RTUStorage
::
getFunction
(
r
->
rtuJack
,
r
->
rtuChan
,
t
);
// т.к. с RTU188 свой обмен
// mbreg и mbfunc поля не используются
return
true
;
}
else
else
{
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRegInfo): Unknown mbtype='"
<<
dev
->
dtype
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRegInfo): Unknown mbtype='"
<<
dev
->
dtype
...
@@ -2092,13 +1877,6 @@ bool MBExchange::initRTUDevice( RTUDevice* d, UniXML_iterator& it )
...
@@ -2092,13 +1877,6 @@ bool MBExchange::initRTUDevice( RTUDevice* d, UniXML_iterator& it )
}
}
d
->
mbaddr
=
ModbusRTU
::
str2mbAddr
(
addr
);
d
->
mbaddr
=
ModbusRTU
::
str2mbAddr
(
addr
);
if
(
d
->
dtype
==
MBExchange
::
dtRTU188
)
{
if
(
!
d
->
rtu
)
d
->
rtu
=
new
RTUStorage
(
d
->
mbaddr
);
}
return
true
;
return
true
;
}
}
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
...
@@ -2111,7 +1889,7 @@ bool MBExchange::initItem( UniXML_iterator& it )
...
@@ -2111,7 +1889,7 @@ bool MBExchange::initItem( UniXML_iterator& it )
string
addr
=
it
.
getProp
(
prop_prefix
+
"mbaddr"
);
string
addr
=
it
.
getProp
(
prop_prefix
+
"mbaddr"
);
if
(
addr
.
empty
()
)
if
(
addr
.
empty
()
)
{
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): Unknown mbaddr
("
<<
prop_prefix
<<
"mbaddr)
='"
<<
addr
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): Unknown mbaddr='"
<<
addr
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
return
false
;
}
}
...
@@ -2124,23 +1902,8 @@ bool MBExchange::initItem( UniXML_iterator& it )
...
@@ -2124,23 +1902,8 @@ bool MBExchange::initItem( UniXML_iterator& it )
return
false
;
return
false
;
}
}
ModbusRTU
::
ModbusData
mbreg
=
0
;
ModbusRTU
::
ModbusData
mbreg
;
int
fn
=
it
.
getIntProp
(
prop_prefix
+
"mbfunc"
);
if
(
dev
->
dtype
==
dtRTU188
)
{
RegInfo
r_tmp
;
if
(
!
initRTU188item
(
it
,
&
r_tmp
)
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): init RTU188 failed for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
mbreg
=
RTUStorage
::
getRegister
(
r_tmp
.
rtuJack
,
r_tmp
.
rtuChan
,
p
.
stype
);
fn
=
RTUStorage
::
getFunction
(
r_tmp
.
rtuJack
,
r_tmp
.
rtuChan
,
p
.
stype
);
}
else
{
if
(
mbregFromID
)
if
(
mbregFromID
)
mbreg
=
p
.
si
.
id
;
// conf->getSensorID(it.getProp("name"));
mbreg
=
p
.
si
.
id
;
// conf->getSensorID(it.getProp("name"));
else
else
...
@@ -2148,22 +1911,13 @@ bool MBExchange::initItem( UniXML_iterator& it )
...
@@ -2148,22 +1911,13 @@ bool MBExchange::initItem( UniXML_iterator& it )
string
reg
=
it
.
getProp
(
prop_prefix
+
"mbreg"
);
string
reg
=
it
.
getProp
(
prop_prefix
+
"mbreg"
);
if
(
reg
.
empty
()
)
if
(
reg
.
empty
()
)
{
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): unknown mbreg("
<<
prop_prefix
<<
")
for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): unknown mbreg
for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
return
false
;
}
}
mbreg
=
ModbusRTU
::
str2mbData
(
reg
);
mbreg
=
ModbusRTU
::
str2mbData
(
reg
);
}
}
if
(
p
.
nbit
!=
-
1
)
int
fn
=
it
.
getIntProp
(
prop_prefix
+
"mbfunc"
);
{
if
(
fn
==
ModbusRTU
::
fnReadCoilStatus
||
fn
==
ModbusRTU
::
fnReadInputStatus
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): MISMATCHED CONFIGURATION! nbit="
<<
p
.
nbit
<<
" func="
<<
fn
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
}
}
// формула для вычисления ID
// формула для вычисления ID
// требования:
// требования:
...
@@ -2338,11 +2092,11 @@ bool MBExchange::initItem( UniXML_iterator& it )
...
@@ -2338,11 +2092,11 @@ bool MBExchange::initItem( UniXML_iterator& it )
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
bool
MBExchange
::
initMTRitem
(
UniXML_iterator
&
it
,
RegInfo
*
p
)
bool
MBExchange
::
initMTRitem
(
UniXML_iterator
&
it
,
RegInfo
*
p
)
{
{
p
->
mtrType
=
MTR
::
str2type
(
it
.
getProp
(
prop_prefix
+
"mtrtype"
));
p
->
mtrType
=
MTR
::
str2type
(
it
.
getProp
(
"mtrtype"
));
if
(
p
->
mtrType
==
MTR
::
mtUnknown
)
if
(
p
->
mtrType
==
MTR
::
mtUnknown
)
{
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(readMTRItem): Unknown mtrtype '"
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(readMTRItem): Unknown mtrtype '"
<<
it
.
getProp
(
prop_prefix
+
"mtrtype"
)
<<
it
.
getProp
(
"mtrtype"
)
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
return
false
;
...
@@ -2351,41 +2105,6 @@ bool MBExchange::initMTRitem( UniXML_iterator& it, RegInfo* p )
...
@@ -2351,41 +2105,6 @@ bool MBExchange::initMTRitem( UniXML_iterator& it, RegInfo* p )
return
true
;
return
true
;
}
}
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
bool
MBExchange
::
initRTU188item
(
UniXML_iterator
&
it
,
RegInfo
*
p
)
{
string
jack
(
it
.
getProp
(
prop_prefix
+
"jack"
));
string
chan
(
it
.
getProp
(
prop_prefix
+
"channel"
));
if
(
jack
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(readRTU188Item): Unknown "
<<
prop_prefix
<<
"jack='' "
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
p
->
rtuJack
=
RTUStorage
::
s2j
(
jack
);
if
(
p
->
rtuJack
==
RTUStorage
::
nUnknown
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(readRTU188Item): Unknown "
<<
prop_prefix
<<
"jack="
<<
jack
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
if
(
chan
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(readRTU188Item): Unknown channel='' "
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
p
->
rtuChan
=
UniSetTypes
::
uni_atoi
(
chan
);
if
(
dlog
.
debugging
(
Debug
::
LEVEL2
)
)
dlog
[
Debug
::
LEVEL2
]
<<
myname
<<
"(readRTU188Item): add jack='"
<<
jack
<<
"'"
<<
" channel='"
<<
p
->
rtuChan
<<
"'"
<<
endl
;
return
true
;
}
// ------------------------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
MBExchange
::
DeviceType
&
dt
)
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
MBExchange
::
DeviceType
&
dt
)
{
{
switch
(
dt
)
switch
(
dt
)
...
@@ -2432,11 +2151,7 @@ std::ostream& operator<<( std::ostream& os, const MBExchange::RSProperty& p )
...
@@ -2432,11 +2151,7 @@ std::ostream& operator<<( std::ostream& os, const MBExchange::RSProperty& p )
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void
MBExchange
::
initDeviceList
()
void
MBExchange
::
initDeviceList
()
{
{
xmlNode
*
respNode
=
0
;
xmlNode
*
respNode
=
conf
->
findNode
(
cnode
,
"DeviceList"
);
UniXML
*
xml
=
conf
->
getConfXML
();
if
(
xml
)
respNode
=
xml
->
extFindNode
(
cnode
,
1
,
1
,
"DeviceList"
);
if
(
respNode
)
if
(
respNode
)
{
{
UniXML_iterator
it1
(
respNode
);
UniXML_iterator
it1
(
respNode
);
...
@@ -2475,25 +2190,7 @@ bool MBExchange::initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXM
...
@@ -2475,25 +2190,7 @@ bool MBExchange::initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXM
d
->
second
->
resp_id
=
conf
->
getSensorID
(
s
);
d
->
second
->
resp_id
=
conf
->
getSensorID
(
s
);
if
(
d
->
second
->
resp_id
==
DefaultObjectId
)
if
(
d
->
second
->
resp_id
==
DefaultObjectId
)
{
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initDeviceInfo): not found ID for respondSensor="
<<
s
<<
endl
;
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initDeviceInfo): not found ID for noRespondSensor="
<<
s
<<
endl
;
return
false
;
}
}
string
mod
(
it
.
getProp
(
"modeSensor"
));
if
(
!
mod
.
empty
()
)
{
d
->
second
->
mode_id
=
conf
->
getSensorID
(
mod
);
if
(
d
->
second
->
mode_id
==
DefaultObjectId
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initDeviceInfo): not found ID for modeSensor="
<<
mod
<<
endl
;
return
false
;
}
UniversalIO
::
IOTypes
m_iotype
=
conf
->
getIOType
(
d
->
second
->
mode_id
);
if
(
m_iotype
!=
UniversalIO
::
AnalogInput
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initDeviceInfo): modeSensor='"
<<
mod
<<
"' must be 'AI'"
<<
endl
;
return
false
;
return
false
;
}
}
}
}
...
@@ -2615,8 +2312,6 @@ void MBExchange::sysCommand( UniSetTypes::SystemMessage *sm )
...
@@ -2615,8 +2312,6 @@ void MBExchange::sysCommand( UniSetTypes::SystemMessage *sm )
initOutput
();
initOutput
();
}
}
updateSM
();
askTimer
(
tmExchange
,
polltime
);
askTimer
(
tmExchange
,
polltime
);
break
;
break
;
}
}
...
@@ -2641,6 +2336,7 @@ void MBExchange::sysCommand( UniSetTypes::SystemMessage *sm )
...
@@ -2641,6 +2336,7 @@ void MBExchange::sysCommand( UniSetTypes::SystemMessage *sm )
if
(
!
force
)
if
(
!
force
)
{
{
uniset_mutex_lock
l
(
pollMutex
,
2000
);
force
=
true
;
force
=
true
;
poll
();
poll
();
force
=
false
;
force
=
false
;
...
@@ -2691,6 +2387,9 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
...
@@ -2691,6 +2387,9 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
throw
SystemError
(
err
.
str
());
throw
SystemError
(
err
.
str
());
}
}
if
(
force_out
)
return
;
try
try
{
{
if
(
sidExchangeMode
!=
DefaultObjectId
)
if
(
sidExchangeMode
!=
DefaultObjectId
)
...
@@ -2708,24 +2407,6 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
...
@@ -2708,24 +2407,6 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
{
RTUDevice
*
d
(
it1
->
second
);
RTUDevice
*
d
(
it1
->
second
);
try
{
if
(
d
->
mode_id
!=
DefaultObjectId
)
shm
->
askSensor
(
d
->
mode_id
,
cmd
);
}
catch
(
UniSetTypes
::
Exception
&
ex
)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(askSensors): "
<<
ex
<<
std
::
endl
;
}
catch
(...)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(askSensors): (mode_id="
<<
d
->
mode_id
<<
").. catch..."
<<
std
::
endl
;
}
if
(
force_out
)
return
;
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
{
if
(
!
isWriteFunction
(
it
->
second
->
mbfunc
)
)
if
(
!
isWriteFunction
(
it
->
second
->
mbfunc
)
)
...
@@ -2743,7 +2424,7 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
...
@@ -2743,7 +2424,7 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
}
}
catch
(...)
catch
(...)
{
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(askSensors):
id="
<<
i
->
si
.
id
<<
"
catch..."
<<
std
::
endl
;
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(askSensors): catch..."
<<
std
::
endl
;
}
}
}
}
}
}
...
@@ -2752,24 +2433,20 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
...
@@ -2752,24 +2433,20 @@ void MBExchange::askSensors( UniversalIO::UIOCommand cmd )
// ------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
void
MBExchange
::
sensorInfo
(
UniSetTypes
::
SensorMessage
*
sm
)
void
MBExchange
::
sensorInfo
(
UniSetTypes
::
SensorMessage
*
sm
)
{
{
if
(
force_out
)
return
;
if
(
sm
->
id
==
sidExchangeMode
)
if
(
sm
->
id
==
sidExchangeMode
)
{
{
exchangeMode
=
sm
->
value
;
exchangeMode
=
sm
->
value
;
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(sensorInfo): exchange MODE="
<<
sm
->
value
<<
std
::
endl
;
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(sensorInfo): exchange MODE="
<<
sm
->
value
<<
std
::
endl
;
//return; // этот датчик может встречаться и в списке обмена.. поэтому делать return нельзя.
return
;
}
}
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
{
RTUDevice
*
d
(
it1
->
second
);
RTUDevice
*
d
(
it1
->
second
);
if
(
sm
->
id
==
d
->
mode_id
)
d
->
mode
=
sm
->
value
;
if
(
force_out
)
continue
;
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
{
if
(
!
isWriteFunction
(
it
->
second
->
mbfunc
)
)
if
(
!
isWriteFunction
(
it
->
second
->
mbfunc
)
)
...
@@ -2834,7 +2511,7 @@ void MBExchange::poll()
...
@@ -2834,7 +2511,7 @@ void MBExchange::poll()
}
}
{
{
uniset_mutex_lock
l
(
pollMutex
,
200
);
uniset_mutex_lock
l
(
pollMutex
);
pollActivated
=
true
;
pollActivated
=
true
;
ptTimeout
.
reset
();
ptTimeout
.
reset
();
}
}
...
@@ -2845,17 +2522,12 @@ void MBExchange::poll()
...
@@ -2845,17 +2522,12 @@ void MBExchange::poll()
if
(
!
checkProcActive
()
)
if
(
!
checkProcActive
()
)
return
;
return
;
bool
allNotRespond
=
true
;
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
{
RTUDevice
*
d
(
it1
->
second
);
RTUDevice
*
d
(
it1
->
second
);
if
(
d
->
mode_id
!=
DefaultObjectId
&&
d
->
mode
==
emSkipExchange
)
if
(
dlog
.
debugging
(
Debug
::
INFO
)
)
continue
;
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(poll): ask addr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(poll): ask addr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" regs="
<<
d
->
regmap
.
size
()
<<
endl
;
<<
" regs="
<<
d
->
regmap
.
size
()
<<
endl
;
d
->
resp_real
=
false
;
d
->
resp_real
=
false
;
...
@@ -2889,13 +2561,11 @@ void MBExchange::poll()
...
@@ -2889,13 +2561,11 @@ void MBExchange::poll()
if
(
ex
.
err
==
ModbusRTU
::
erTimeOut
&&
!
d
->
ask_every_reg
)
if
(
ex
.
err
==
ModbusRTU
::
erTimeOut
&&
!
d
->
ask_every_reg
)
break
;
break
;
if
(
ex
.
err
==
ModbusRTU
::
erNoError
)
// если контроллер хоть что-то ответил, то вроде как связь есть..
if
(
ex
.
err
!=
ModbusRTU
::
erTimeOut
)
d
->
resp_real
=
true
;
d
->
resp_real
=
true
;
}
}
if
(
d
->
resp_real
)
allNotRespond
=
false
;
if
(
it
==
d
->
regmap
.
end
()
)
if
(
it
==
d
->
regmap
.
end
()
)
break
;
break
;
...
@@ -2915,7 +2585,7 @@ void MBExchange::poll()
...
@@ -2915,7 +2585,7 @@ void MBExchange::poll()
}
}
{
{
uniset_mutex_lock
l
(
pollMutex
,
120
);
uniset_mutex_lock
l
(
pollMutex
);
pollActivated
=
false
;
pollActivated
=
false
;
}
}
...
@@ -2926,128 +2596,20 @@ void MBExchange::poll()
...
@@ -2926,128 +2596,20 @@ void MBExchange::poll()
updateSM
();
updateSM
();
// check thresholds
// check thresholds
for
(
ThresholdList
::
iterator
t
=
thrlist
.
begin
();
t
!=
thrlist
.
end
();
++
t
)
{
if
(
!
checkProcActive
()
)
return
;
IOBase
::
processingThreshold
(
&
(
*
t
),
shm
,
force
);
}
if
(
trReopen
.
hi
(
allNotRespond
)
)
ptReopen
.
reset
();
if
(
allNotRespond
&&
ptReopen
.
checkTime
()
)
{
uniset_mutex_lock
l
(
pollMutex
,
300
);
if
(
dlog
.
debugging
(
Debug
::
WARN
)
)
dlog
[
Debug
::
WARN
]
<<
myname
<<
": REOPEN timeout..("
<<
ptReopen
.
getInterval
()
<<
")"
<<
endl
;
mb
=
initMB
(
true
);
ptReopen
.
reset
();
}
// printMap(rmap);
}
// -----------------------------------------------------------------------------
bool
MBExchange
::
RTUDevice
::
checkRespond
()
{
bool
prev
=
resp_state
;
if
(
resp_ptTimeout
.
getInterval
()
<=
0
)
{
resp_state
=
resp_real
;
return
(
prev
!=
resp_state
);
}
if
(
resp_trTimeout
.
hi
(
resp_state
&&
!
resp_real
)
)
resp_ptTimeout
.
reset
();
if
(
resp_real
)
resp_state
=
true
;
else
if
(
resp_state
&&
!
resp_real
&&
resp_ptTimeout
.
checkTime
()
)
resp_state
=
false
;
// если ещё не инициализировали значение в SM
// то возвращаем true, чтобы оно принудительно сохранилось
if
(
!
resp_init
)
{
resp_state
=
resp_real
;
resp_init
=
true
;
prev
=
resp_state
;
return
true
;
}
return
(
prev
!=
resp_state
);
}
// -----------------------------------------------------------------------------
void
MBExchange
::
updateRespondSensors
()
{
bool
chanTimeout
=
false
;
{
uniset_mutex_lock
l
(
pollMutex
,
240
);
chanTimeout
=
pollActivated
&&
ptTimeout
.
checkTime
();
}
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
{
RTUDevice
*
d
(
it1
->
second
);
RTUDevice
*
d
(
it1
->
second
);
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
if
(
chanTimeout
)
it1
->
second
->
resp_real
=
false
;
if
(
dlog
.
debugging
(
Debug
::
LEVEL4
)
)
{
dlog
[
Debug
::
LEVEL4
]
<<
myname
<<
": check respond addr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" respond_id="
<<
d
->
resp_id
<<
" real="
<<
d
->
resp_real
<<
" state="
<<
d
->
resp_state
<<
endl
;
}
if
(
d
->
checkRespond
()
&&
d
->
resp_id
!=
DefaultObjectId
)
{
try
{
bool
set
=
d
->
resp_invert
?
!
d
->
resp_state
:
d
->
resp_state
;
shm
->
localSaveState
(
d
->
resp_dit
,
d
->
resp_id
,
set
,
getId
());
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(step): (respond) "
<<
ex
<<
std
::
endl
;
}
}
}
}
// -----------------------------------------------------------------------------
void
MBExchange
::
execute
()
{
no_extimer
=
true
;
try
{
{
askTimer
(
tmExchange
,
0
);
if
(
!
checkProcActive
()
)
}
return
;
catch
(...){}
initMB
(
false
);
while
(
1
)
RegInfo
*
r
(
it
->
second
);
{
for
(
PList
::
iterator
i
=
r
->
slst
.
begin
();
i
!=
r
->
slst
.
end
();
++
i
)
try
IOBase
::
processingThreshold
(
&
(
*
i
),
shm
,
force
);
{
step
();
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(execute): "
<<
ex
<<
std
::
endl
;
}
}
catch
(...)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(execute): catch ..."
<<
endl
;
}
}
msleep
(
polltime
);
// printMap(rmap);
}
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
extensions/ModbusMaster/RTUStorage.cc
View file @
df497744
...
@@ -111,9 +111,9 @@ void RTUStorage::poll( ModbusRTUMaster* mb )
...
@@ -111,9 +111,9 @@ void RTUStorage::poll( ModbusRTUMaster* mb )
// -----------------------------------
// -----------------------------------
}
}
// опрос UNIO48 DO
if
(
pollUNIO
)
if
(
pollUNIO
)
{
{
// опрос UNIO48 DO
{
{
ModbusRTU
::
ReadCoilRetMessage
ret
=
mb
->
read01
(
addr
,
16
,
48
);
ModbusRTU
::
ReadCoilRetMessage
ret
=
mb
->
read01
(
addr
,
16
,
48
);
ModbusRTU
::
DataBits
bits
;
ModbusRTU
::
DataBits
bits
;
...
@@ -179,7 +179,7 @@ float RTUStorage::getFloat( RTUJack jack, unsigned short int chan, UniversalIO::
...
@@ -179,7 +179,7 @@ float RTUStorage::getFloat( RTUJack jack, unsigned short int chan, UniversalIO::
case
nJ1
:
case
nJ1
:
return
unio_ai
[
chan
];
return
unio_ai
[
chan
];
case
nJ2
:
case
nJ2
:
return
unio_ai
[
12
+
chan
];
return
unio_ai
[
24
+
chan
];
case
nJ5
:
case
nJ5
:
return
dio_ai
[
chan
];
return
dio_ai
[
chan
];
case
nX1
:
case
nX1
:
...
@@ -201,7 +201,7 @@ float RTUStorage::getFloat( RTUJack jack, unsigned short int chan, UniversalIO::
...
@@ -201,7 +201,7 @@ float RTUStorage::getFloat( RTUJack jack, unsigned short int chan, UniversalIO::
case
nJ1
:
case
nJ1
:
return
unio_ao
[
chan
];
return
unio_ao
[
chan
];
case
nJ2
:
case
nJ2
:
return
unio_ao
[
12
+
chan
];
return
unio_ao
[
24
+
chan
];
case
nJ5
:
case
nJ5
:
return
dio_ao
[
chan
];
return
dio_ao
[
chan
];
case
nX1
:
case
nX1
:
...
@@ -353,84 +353,6 @@ ModbusRTU::ModbusData RTUStorage::getRegister( RTUJack jack, unsigned short chan
...
@@ -353,84 +353,6 @@ ModbusRTU::ModbusData RTUStorage::getRegister( RTUJack jack, unsigned short chan
return
-
1
;
return
-
1
;
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ModbusRTU
::
SlaveFunctionCode
RTUStorage
::
getFunction
(
RTUJack
jack
,
unsigned
short
chan
,
UniversalIO
::
IOTypes
t
)
{
if
(
t
==
UniversalIO
::
AnalogInput
)
{
switch
(
jack
)
{
case
nJ1
:
case
nJ2
:
case
nJ5
:
case
nX1
:
case
nX2
:
return
ModbusRTU
::
fnReadInputRegisters
;
default
:
break
;
}
return
ModbusRTU
::
fnUnknown
;
}
if
(
t
==
UniversalIO
::
AnalogOutput
)
{
switch
(
jack
)
{
case
nJ1
:
case
nJ2
:
case
nJ5
:
return
ModbusRTU
::
fnReadOutputRegisters
;
case
nX1
:
case
nX2
:
return
ModbusRTU
::
fnReadInputRegisters
;
default
:
break
;
}
return
ModbusRTU
::
fnUnknown
;
}
if
(
t
==
UniversalIO
::
DigitalInput
)
{
switch
(
jack
)
{
case
nJ1
:
case
nJ2
:
case
nJ5
:
case
nX4
:
case
nX5
:
return
ModbusRTU
::
fnReadInputStatus
;
default
:
break
;
}
return
ModbusRTU
::
fnUnknown
;
}
if
(
t
==
UniversalIO
::
DigitalOutput
)
{
switch
(
jack
)
{
case
nJ1
:
case
nJ2
:
case
nJ5
:
return
ModbusRTU
::
fnReadCoilStatus
;
default
:
break
;
}
return
ModbusRTU
::
fnUnknown
;
}
return
ModbusRTU
::
fnUnknown
;
}
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUStorage
&
m
)
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUStorage
&
m
)
{
{
os
<<
"-------------------"
<<
endl
os
<<
"-------------------"
<<
endl
...
@@ -559,22 +481,22 @@ void RTUStorage::print()
...
@@ -559,22 +481,22 @@ void RTUStorage::print()
cout
<<
this
;
cout
<<
this
;
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
RTUStorage
::
RTUJack
RTUStorage
::
s2j
(
const
std
::
string
&
jack
)
RTUStorage
::
RTUJack
RTUStorage
::
s2j
(
const
std
::
string
jack
)
{
{
if
(
jack
==
"J1"
||
jack
==
"j1"
)
if
(
jack
==
"J1"
)
return
nJ1
;
return
nJ1
;
if
(
jack
==
"J2"
||
jack
==
"j2"
)
if
(
jack
==
"J2"
)
return
nJ2
;
return
nJ2
;
if
(
jack
==
"J5"
||
jack
==
"j5"
)
if
(
jack
==
"J5"
)
return
nJ5
;
return
nJ5
;
if
(
jack
==
"X1"
||
jack
==
"x1"
)
if
(
jack
==
"X1"
)
return
nX1
;
return
nX1
;
if
(
jack
==
"X2"
||
jack
==
"x2"
)
if
(
jack
==
"X2"
)
return
nX2
;
return
nX2
;
if
(
jack
==
"X4"
||
jack
==
"x4"
)
if
(
jack
==
"X4"
)
return
nX4
;
return
nX4
;
if
(
jack
==
"X5"
||
jack
==
"x5"
)
if
(
jack
==
"X5"
)
return
nX5
;
return
nX5
;
return
nUnknown
;
return
nUnknown
;
...
...
extensions/ModbusMaster/RTUStorage.h
View file @
df497744
...
@@ -38,7 +38,7 @@ class RTUStorage
...
@@ -38,7 +38,7 @@ class RTUStorage
nX5
// DI (8)
nX5
// DI (8)
};
};
static
RTUJack
s2j
(
const
std
::
string
&
jack
);
static
RTUJack
s2j
(
const
std
::
string
jack
);
static
std
::
string
j2s
(
RTUJack
j
);
static
std
::
string
j2s
(
RTUJack
j
);
long
getInt
(
RTUJack
jack
,
unsigned
short
channel
,
UniversalIO
::
IOTypes
t
);
long
getInt
(
RTUJack
jack
,
unsigned
short
channel
,
UniversalIO
::
IOTypes
t
);
...
@@ -47,8 +47,6 @@ class RTUStorage
...
@@ -47,8 +47,6 @@ class RTUStorage
static
ModbusRTU
::
ModbusData
getRegister
(
RTUJack
jack
,
unsigned
short
channel
,
UniversalIO
::
IOTypes
t
);
static
ModbusRTU
::
ModbusData
getRegister
(
RTUJack
jack
,
unsigned
short
channel
,
UniversalIO
::
IOTypes
t
);
static
ModbusRTU
::
SlaveFunctionCode
getFunction
(
RTUJack
jack
,
unsigned
short
channel
,
UniversalIO
::
IOTypes
t
);
// ДОДЕЛАТЬ: setState, setValue
// ДОДЕЛАТЬ: setState, setValue
void
print
();
void
print
();
...
...
extensions/RTUExchange/Makefile.am
View file @
df497744
...
@@ -8,16 +8,18 @@ libUniSetRTU_la_LDFLAGS = -version-info $(URTU_VER)
...
@@ -8,16 +8,18 @@ libUniSetRTU_la_LDFLAGS = -version-info $(URTU_VER)
libUniSetRTU_la_LIBADD
=
$(top_builddir)
/lib/libUniSet.la
\
libUniSetRTU_la_LIBADD
=
$(top_builddir)
/lib/libUniSet.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(top_builddir)
/extensions/ModbusMaster/libMBMaster.la
\
$(SIGC_LIBS)
$(SIGC_LIBS)
libUniSetRTU_la_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
$(SIGC_CFLAGS)
libUniSetRTU_la_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
-I
$(top_builddir)
/extensions/ModbusMaster
$(SIGC_CFLAGS)
libUniSetRTU_la_SOURCES
=
RTU
Storage.cc RTU
Exchange.cc
libUniSetRTU_la_SOURCES
=
RTUExchange.cc
@PACKAGE@
_rtuexchange_SOURCES
=
rtuexchange.cc
@PACKAGE@
_rtuexchange_SOURCES
=
rtuexchange.cc
@PACKAGE@
_rtuexchange_LDADD
=
libUniSetRTU.la
$(top_builddir)
/lib/libUniSet.la
\
@PACKAGE@
_rtuexchange_LDADD
=
libUniSetRTU.la
$(top_builddir)
/lib/libUniSet.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/SharedMemory/libUniSetSharedMemory.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
\
$(top_builddir)
/extensions/ModbusMaster/libMBMaster.la
\
$(SIGC_LIBS)
$(SIGC_LIBS)
@PACKAGE@
_rtuexchange_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
$(SIGC_CFLAGS)
@PACKAGE@
_rtuexchange_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/SharedMemory
-I
$(top_builddir)
/extensions/ModbusMaster
$(SIGC_CFLAGS)
@PACKAGE@
_mtr_conv_SOURCES
=
mtrconv.cc
@PACKAGE@
_mtr_conv_SOURCES
=
mtrconv.cc
@PACKAGE@
_mtr_conv_LDADD
=
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
$(top_builddir)
/lib/libUniSet.la
@PACKAGE@
_mtr_conv_LDADD
=
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
$(top_builddir)
/lib/libUniSet.la
...
@@ -31,8 +33,10 @@ libUniSetRTU_la_SOURCES = RTUStorage.cc RTUExchange.cc
...
@@ -31,8 +33,10 @@ libUniSetRTU_la_SOURCES = RTUStorage.cc RTUExchange.cc
@PACKAGE@
_vtconv_LDADD
=
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
$(top_builddir)
/lib/libUniSet.la
@PACKAGE@
_vtconv_LDADD
=
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
$(top_builddir)
/lib/libUniSet.la
@PACKAGE@
_vtconv_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
@PACKAGE@
_vtconv_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
@PACKAGE@
_rtu188_state_LDADD
=
libUniSetRTU.la
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
$(top_builddir)
/lib/libUniSet.la
@PACKAGE@
_rtu188_state_LDADD
=
libUniSetRTU.la
\
@PACKAGE@
_rtu188_state__CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
$(top_builddir)
/extensions/lib/libUniSetExtensions.la
$(top_builddir)
/lib/libUniSet.la
\
$(top_builddir)
/extensions/ModbusMaster/libMBMaster.la
@PACKAGE@
_rtu188_state_CXXFLAGS
=
-I
$(top_builddir)
/extensions/include
-I
$(top_builddir)
/extensions/ModbusMaster
@PACKAGE@
_rtu188_state_SOURCES
=
rtustate.cc
@PACKAGE@
_rtu188_state_SOURCES
=
rtustate.cc
# install
# install
...
...
extensions/RTUExchange/RTUStorage.cc
deleted
100644 → 0
View file @
a15d2cc4
// -----------------------------------------------------------------------------
#include <cmath>
#include <iostream>
#include <iomanip>
#include <string>
#include "modbus/ModbusRTUMaster.h"
#include "RTUStorage.h"
// -----------------------------------------------------------------------------
using
namespace
std
;
// -----------------------------------------------------------------------------
RTUStorage
::
RTUStorage
(
ModbusRTU
::
ModbusAddr
a
)
:
addr
(
a
),
pingOK
(
false
),
pollADC
(
true
),
pollDI
(
true
),
pollDIO
(
true
),
pollUNIO
(
true
)
{
memset
(
adc
,
0
,
sizeof
(
adc
));
memset
(
di
,
0
,
sizeof
(
di
));
memset
(
dio_do
,
0
,
sizeof
(
dio_do
));
memset
(
dio_di
,
0
,
sizeof
(
dio_di
));
memset
(
dio_ai
,
0
,
sizeof
(
dio_ai
));
memset
(
dio_ao
,
0
,
sizeof
(
dio_ao
));
memset
(
unio_di
,
0
,
sizeof
(
unio_di
));
memset
(
unio_do
,
0
,
sizeof
(
unio_do
));
memset
(
unio_ai
,
0
,
sizeof
(
unio_ai
));
memset
(
unio_ao
,
0
,
sizeof
(
unio_ao
));
}
// -----------------------------------------------------------------------------
RTUStorage
::~
RTUStorage
()
{
}
// -----------------------------------------------------------------------------
void
RTUStorage
::
poll
(
ModbusRTUMaster
*
mb
)
throw
(
ModbusRTU
::
mbException
)
{
try
{
pingOK
=
true
;
// опрос АЦП
if
(
pollADC
)
{
ModbusRTU
::
ReadInputRetMessage
ret
=
mb
->
read04
(
addr
,
1016
,
16
);
for
(
int
i
=
0
,
k
=
0
;
i
<
16
;
i
+=
2
,
k
++
)
adc
[
k
]
=
ModbusRTU
::
dat2f
(
ret
.
data
[
i
],
ret
.
data
[
i
+
1
]);
}
// -----------------------------------
// опрос 16 DI
if
(
pollDI
)
{
ModbusRTU
::
ReadInputStatusRetMessage
ret
=
mb
->
read02
(
addr
,
0
,
16
);
ModbusRTU
::
DataBits
bits
;
for
(
int
b
=
0
;
b
<
2
;
b
++
)
{
if
(
ret
.
getData
(
b
,
bits
)
)
{
for
(
int
i
=
0
;
i
<
8
;
i
++
)
di
[
i
+
8
*
b
]
=
bits
[
i
];
}
}
}
// -----------------------------------
// опрос 16DIO DO
if
(
pollDIO
)
{
{
ModbusRTU
::
ReadCoilRetMessage
ret
=
mb
->
read01
(
addr
,
0
,
16
);
ModbusRTU
::
DataBits
bits
;
for
(
int
b
=
0
;
b
<
2
;
b
++
)
{
if
(
ret
.
getData
(
b
,
bits
)
)
{
for
(
int
i
=
0
;
i
<
8
;
i
++
)
dio_do
[
i
+
8
*
b
]
=
bits
[
i
];
}
}
}
// -----------------------------------
// опрос 16DIO DI
{
ModbusRTU
::
ReadInputStatusRetMessage
ret
=
mb
->
read02
(
addr
,
16
,
16
);
ModbusRTU
::
DataBits
bits
;
for
(
int
b
=
0
;
b
<
2
;
b
++
)
{
if
(
ret
.
getData
(
b
,
bits
)
)
{
for
(
int
i
=
0
;
i
<
8
;
i
++
)
dio_di
[
i
+
8
*
b
]
=
bits
[
i
];
}
}
}
// -----------------------------------
// опрос 16DIO AI
{
ModbusRTU
::
ReadInputRetMessage
ret
=
mb
->
read04
(
addr
,
1000
,
16
);
int
k
=
0
;
for
(
int
i
=
0
;
i
<
16
;
i
+=
2
,
k
++
)
dio_ai
[
k
]
=
ModbusRTU
::
dat2f
(
ret
.
data
[
i
],
ret
.
data
[
i
+
1
]);
}
// -----------------------------------
// опрос 16DIO AO
{
ModbusRTU
::
ReadOutputRetMessage
ret
=
mb
->
read03
(
addr
,
1000
,
16
);
int
k
=
0
;
for
(
int
i
=
0
;
i
<
16
;
i
+=
2
,
k
++
)
dio_ao
[
k
]
=
ModbusRTU
::
dat2f
(
ret
.
data
[
i
],
ret
.
data
[
i
+
1
]);
}
// -----------------------------------
}
// опрос UNIO48 DO
if
(
pollUNIO
)
{
{
ModbusRTU
::
ReadCoilRetMessage
ret
=
mb
->
read01
(
addr
,
16
,
48
);
ModbusRTU
::
DataBits
bits
;
for
(
int
b
=
0
;
b
<
8
;
b
++
)
{
if
(
ret
.
getData
(
b
,
bits
)
)
{
for
(
int
i
=
0
;
i
<
8
;
i
++
)
unio_do
[
i
+
8
*
b
]
=
bits
[
i
];
}
}
}
// -----------------------------------
// опрос UNIO48 DI
{
ModbusRTU
::
ReadInputStatusRetMessage
ret
=
mb
->
read02
(
addr
,
32
,
48
);
ModbusRTU
::
DataBits
bits
;
for
(
int
b
=
0
;
b
<
8
;
b
++
)
{
if
(
ret
.
getData
(
b
,
bits
)
)
{
for
(
int
i
=
0
;
i
<
8
;
i
++
)
unio_di
[
i
+
8
*
b
]
=
bits
[
i
];
}
}
}
// -----------------------------------
// опрос UNIO48 AI
{
ModbusRTU
::
ReadInputRetMessage
ret
=
mb
->
read04
(
addr
,
1032
,
48
);
int
k
=
0
;
for
(
int
i
=
0
;
i
<
48
;
i
+=
2
,
k
++
)
unio_ai
[
k
]
=
ModbusRTU
::
dat2f
(
ret
.
data
[
i
],
ret
.
data
[
i
+
1
]);
}
// -----------------------------------
// опрос UNIO48 AO
{
ModbusRTU
::
ReadOutputRetMessage
ret
=
mb
->
read03
(
addr
,
1016
,
48
);
int
k
=
0
;
for
(
int
i
=
0
;
i
<
48
;
i
+=
2
,
k
++
)
unio_ao
[
k
]
=
ModbusRTU
::
dat2f
(
ret
.
data
[
i
],
ret
.
data
[
i
+
1
]);
}
}
}
catch
(...)
{
pingOK
=
false
;
throw
;
}
}
// -----------------------------------------------------------------------------
long
RTUStorage
::
getInt
(
RTUJack
jack
,
unsigned
short
int
chan
,
UniversalIO
::
IOTypes
t
)
{
return
lroundf
(
getFloat
(
jack
,
chan
,
t
)
);
}
// -----------------------------------------------------------------------------
float
RTUStorage
::
getFloat
(
RTUJack
jack
,
unsigned
short
int
chan
,
UniversalIO
::
IOTypes
t
)
{
if
(
t
==
UniversalIO
::
AnalogInput
)
{
switch
(
jack
)
{
case
nJ1
:
return
unio_ai
[
chan
];
case
nJ2
:
return
unio_ai
[
24
+
chan
];
case
nJ5
:
return
dio_ai
[
chan
];
case
nX1
:
return
adc
[
chan
];
case
nX2
:
return
adc
[
4
+
chan
];
default
:
break
;
}
return
0
;
}
if
(
t
==
UniversalIO
::
AnalogOutput
)
{
switch
(
jack
)
{
case
nJ1
:
return
unio_ao
[
chan
];
case
nJ2
:
return
unio_ao
[
24
+
chan
];
case
nJ5
:
return
dio_ao
[
chan
];
case
nX1
:
return
adc
[
chan
];
case
nX2
:
return
adc
[
4
+
chan
];
default
:
break
;
}
return
0
;
}
return
0
;
}
// -----------------------------------------------------------------------------
bool
RTUStorage
::
getState
(
RTUJack
jack
,
unsigned
short
int
chan
,
UniversalIO
::
IOTypes
t
)
{
if
(
t
==
UniversalIO
::
DigitalInput
)
{
switch
(
jack
)
{
case
nJ1
:
return
unio_di
[
chan
];
case
nJ2
:
return
unio_di
[
24
+
chan
];
case
nJ5
:
return
dio_di
[
chan
];
case
nX4
:
return
di
[
chan
];
case
nX5
:
return
di
[
8
+
chan
];
default
:
break
;
}
return
false
;
}
if
(
t
==
UniversalIO
::
DigitalOutput
)
{
switch
(
jack
)
{
case
nJ1
:
return
unio_do
[
chan
];
case
nJ2
:
return
unio_do
[
24
+
chan
];
case
nJ5
:
return
dio_do
[
chan
];
default
:
break
;
}
return
false
;
}
return
false
;
}
// -----------------------------------------------------------------------------
ModbusRTU
::
ModbusData
RTUStorage
::
getRegister
(
RTUJack
jack
,
unsigned
short
chan
,
UniversalIO
::
IOTypes
t
)
{
if
(
t
==
UniversalIO
::
AnalogInput
)
{
switch
(
jack
)
{
case
nJ1
:
return
1032
+
chan
;
case
nJ2
:
return
1032
+
24
+
chan
;
case
nJ5
:
return
1000
+
chan
;
case
nX1
:
return
1016
+
chan
;
case
nX2
:
return
1016
+
4
+
chan
;
default
:
break
;
}
return
-
1
;
}
if
(
t
==
UniversalIO
::
AnalogOutput
)
{
switch
(
jack
)
{
case
nJ1
:
return
1016
+
chan
;
case
nJ2
:
return
1016
+
24
+
chan
;
case
nJ5
:
return
1000
+
chan
;
case
nX1
:
return
1016
+
chan
;
case
nX2
:
return
1016
+
4
+
chan
;
default
:
break
;
}
return
-
1
;
}
if
(
t
==
UniversalIO
::
DigitalInput
)
{
switch
(
jack
)
{
case
nJ1
:
return
32
+
chan
;
case
nJ2
:
return
32
+
24
+
chan
;
case
nJ5
:
return
16
+
chan
;
case
nX4
:
return
chan
;
case
nX5
:
return
8
+
chan
;
default
:
break
;
}
return
-
1
;
}
if
(
t
==
UniversalIO
::
DigitalOutput
)
{
switch
(
jack
)
{
case
nJ1
:
return
16
+
chan
;
case
nJ2
:
return
16
+
24
+
chan
;
case
nJ5
:
return
chan
;
default
:
break
;
}
return
-
1
;
}
return
-
1
;
}
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUStorage
&
m
)
{
os
<<
"-------------------"
<<
endl
<<
" АЦП (8 каналов): "
<<
endl
;
for
(
int
i
=
0
;
i
<
8
;
i
++
)
// номера каналов
os
<<
setw
(
12
)
<<
i
<<
"|"
;
os
<<
endl
;
for
(
int
i
=
0
;
i
<
8
;
i
++
)
os
<<
setw
(
12
)
<<
m
.
adc
[
i
]
<<
"|"
;
os
<<
endl
;
os
<<
"-------------------"
<<
endl
<<
" DI (16 каналов): "
<<
endl
;
for
(
int
i
=
0
;
i
<
16
;
i
++
)
// номера каналов
os
<<
setw
(
2
)
<<
i
<<
"|"
;
os
<<
endl
;
for
(
int
i
=
0
;
i
<
16
;
i
++
)
os
<<
setw
(
2
)
<<
m
.
di
[
i
]
<<
"|"
;
os
<<
endl
;
os
<<
"-------------------"
<<
endl
<<
" DIO DO(16 каналов): "
<<
endl
;
for
(
int
i
=
0
;
i
<
16
;
i
++
)
// номера каналов
os
<<
setw
(
2
)
<<
i
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
0
;
i
<
16
;
i
++
)
os
<<
setw
(
2
)
<<
m
.
dio_do
[
i
]
<<
" | "
;
os
<<
endl
;
os
<<
"-------------------"
<<
endl
<<
" DIO DI(16 каналов): "
<<
endl
;
for
(
int
i
=
0
;
i
<
16
;
i
++
)
// номера каналов
os
<<
setw
(
2
)
<<
i
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
0
;
i
<
16
;
i
++
)
os
<<
setw
(
2
)
<<
m
.
dio_di
[
i
]
<<
" | "
;
os
<<
endl
;
os
<<
"-------------------"
<<
endl
<<
" DIO AI (16 каналов): "
<<
endl
;
for
(
int
i
=
0
;
i
<
16
;
i
++
)
// номера каналов
os
<<
setw
(
2
)
<<
i
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
0
;
i
<
16
;
i
++
)
os
<<
setw
(
2
)
<<
m
.
dio_ai
[
i
]
<<
" | "
;
os
<<
endl
;
os
<<
"-------------------"
<<
endl
<<
" DIO AO (16 каналов): "
<<
endl
;
for
(
int
i
=
0
;
i
<
16
;
i
++
)
// номера каналов
os
<<
setw
(
2
)
<<
i
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
0
;
i
<
16
;
i
++
)
os
<<
setw
(
2
)
<<
m
.
dio_ao
[
i
]
<<
" | "
;
os
<<
endl
;
os
<<
"-------------------"
<<
endl
<<
" UNIO48 DI: "
<<
endl
;
for
(
int
i
=
0
;
i
<
24
;
i
++
)
// номера каналов
os
<<
setw
(
2
)
<<
i
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
0
;
i
<
24
;
i
++
)
os
<<
setw
(
2
)
<<
m
.
unio_di
[
i
]
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
24
;
i
<
48
;
i
++
)
// номера каналов
os
<<
setw
(
2
)
<<
i
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
24
;
i
<
48
;
i
++
)
os
<<
setw
(
2
)
<<
m
.
unio_di
[
i
]
<<
" | "
;
os
<<
endl
;
os
<<
"-------------------"
<<
endl
<<
" UNIO48 DO: "
<<
endl
;
for
(
int
i
=
0
;
i
<
24
;
i
++
)
// номера каналов
os
<<
setw
(
2
)
<<
i
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
0
;
i
<
24
;
i
++
)
os
<<
setw
(
2
)
<<
m
.
unio_do
[
i
]
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
24
;
i
<
48
;
i
++
)
// номера каналов
os
<<
setw
(
2
)
<<
i
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
24
;
i
<
48
;
i
++
)
os
<<
setw
(
2
)
<<
m
.
unio_do
[
i
]
<<
" | "
;
os
<<
endl
;
os
<<
"-------------------"
<<
endl
<<
" UNIO48 AI: "
<<
endl
;
for
(
int
i
=
0
;
i
<
12
;
i
++
)
// номера каналов
os
<<
setw
(
6
)
<<
i
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
0
;
i
<
12
;
i
++
)
os
<<
setw
(
6
)
<<
m
.
unio_ai
[
i
]
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
12
;
i
<
24
;
i
++
)
// номера каналов
os
<<
setw
(
6
)
<<
i
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
12
;
i
<
24
;
i
++
)
os
<<
setw
(
6
)
<<
m
.
unio_ai
[
i
]
<<
" | "
;
os
<<
endl
;
os
<<
"-------------------"
<<
endl
<<
" UNIO48 AO: "
<<
endl
;
for
(
int
i
=
0
;
i
<
12
;
i
++
)
// номера каналов
os
<<
setw
(
6
)
<<
i
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
0
;
i
<
12
;
i
++
)
os
<<
setw
(
6
)
<<
m
.
unio_ao
[
i
]
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
12
;
i
<
24
;
i
++
)
// номера каналов
os
<<
setw
(
6
)
<<
i
<<
" | "
;
os
<<
endl
;
for
(
int
i
=
12
;
i
<
24
;
i
++
)
os
<<
setw
(
6
)
<<
m
.
unio_ao
[
i
]
<<
" | "
;
os
<<
endl
;
return
os
;
}
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUStorage
*
m
)
{
return
os
<<
(
*
m
);
}
// -----------------------------------------------------------------------------
void
RTUStorage
::
print
()
{
cout
<<
this
;
}
// -----------------------------------------------------------------------------
RTUStorage
::
RTUJack
RTUStorage
::
s2j
(
const
std
::
string
jack
)
{
if
(
jack
==
"J1"
)
return
nJ1
;
if
(
jack
==
"J2"
)
return
nJ2
;
if
(
jack
==
"J5"
)
return
nJ5
;
if
(
jack
==
"X1"
)
return
nX1
;
if
(
jack
==
"X2"
)
return
nX2
;
if
(
jack
==
"X4"
)
return
nX4
;
if
(
jack
==
"X5"
)
return
nX5
;
return
nUnknown
;
}
// -----------------------------------------------------------------------------
std
::
string
RTUStorage
::
j2s
(
RTUStorage
::
RTUJack
jack
)
{
if
(
jack
==
nJ1
)
return
"J1"
;
if
(
jack
==
nJ2
)
return
"J2"
;
if
(
jack
==
nJ5
)
return
"J5"
;
if
(
jack
==
nX1
)
return
"X1"
;
if
(
jack
==
nX2
)
return
"X2"
;
if
(
jack
==
nX4
)
return
"X4"
;
if
(
jack
==
nX5
)
return
"X5"
;
return
""
;
}
// -----------------------------------------------------------------------------
extensions/RTUExchange/RTUStorage.h
deleted
100644 → 0
View file @
a15d2cc4
// --------------------------------------------------------------------------
#ifndef _RTUSTORAGE_H_
#define _RTUSTORAGE_H_
// -----------------------------------------------------------------------------
#include <ostream>
#include <string>
#include "modbus/ModbusTypes.h"
#include "UniSetTypes.h"
// -----------------------------------------------------------------------------
class
ModbusRTUMaster
;
// -----------------------------------------------------------------------------
class
RTUStorage
{
public
:
RTUStorage
(
ModbusRTU
::
ModbusAddr
addr
);
~
RTUStorage
();
void
poll
(
ModbusRTUMaster
*
mb
)
throw
(
ModbusRTU
::
mbException
);
inline
ModbusRTU
::
ModbusAddr
getAddress
(){
return
addr
;
}
inline
bool
ping
(){
return
pingOK
;
}
inline
void
setPollADC
(
bool
set
){
pollADC
=
set
;
}
inline
void
setPollDI
(
bool
set
){
pollDI
=
set
;
}
inline
void
setPollDIO
(
bool
set
){
pollDIO
=
set
;
}
inline
void
setPollUNIO
(
bool
set
){
pollUNIO
=
set
;
}
enum
RTUJack
{
nUnknown
,
nJ1
,
// UNIO48 (FPGA0)
nJ2
,
// UNIO48 (FPGA1)
nJ5
,
// DIO 16
nX1
,
// АЦП (8)
nX2
,
// АЦП (8)
nX4
,
// DI (8)
nX5
// DI (8)
};
static
RTUJack
s2j
(
const
std
::
string
jack
);
static
std
::
string
j2s
(
RTUJack
j
);
long
getInt
(
RTUJack
jack
,
unsigned
short
channel
,
UniversalIO
::
IOTypes
t
);
float
getFloat
(
RTUJack
jack
,
unsigned
short
channel
,
UniversalIO
::
IOTypes
t
);
bool
getState
(
RTUJack
jack
,
unsigned
short
channel
,
UniversalIO
::
IOTypes
t
);
static
ModbusRTU
::
ModbusData
getRegister
(
RTUJack
jack
,
unsigned
short
channel
,
UniversalIO
::
IOTypes
t
);
// ДОДЕЛАТЬ: setState, setValue
void
print
();
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUStorage
&
m
);
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
RTUStorage
*
m
);
protected
:
ModbusRTU
::
ModbusAddr
addr
;
bool
pingOK
;
bool
pollADC
;
bool
pollDI
;
bool
pollDIO
;
bool
pollUNIO
;
float
adc
[
8
];
// АЦП
bool
di
[
16
];
// Порт 16DI
bool
dio_do
[
16
];
// Порт 16DIO DO
bool
dio_di
[
16
];
// Порт 16DIO DI
float
dio_ai
[
16
];
// Порт 16DIO AI
float
dio_ao
[
16
];
// Порт 16DIO AO
bool
unio_do
[
48
];
// Порт UNIO48 DO
bool
unio_di
[
48
];
// Порт UNIO48 DI
float
unio_ai
[
24
];
// Порт UNIO48 AI
float
unio_ao
[
24
];
// Порт UNIO48 AO
};
// --------------------------------------------------------------------------
#endif // _RTUSTORAGE_H_
// -----------------------------------------------------------------------------
extensions/lib/MBExchange.cc
deleted
100644 → 0
View file @
a15d2cc4
// -----------------------------------------------------------------------------
#include <cmath>
#include <limits>
#include <sstream>
#include <Exceptions.h>
#include <extensions/Extensions.h>
#include "MBExchange.h"
// -----------------------------------------------------------------------------
using
namespace
std
;
using
namespace
UniSetTypes
;
using
namespace
UniSetExtensions
;
// -----------------------------------------------------------------------------
MBExchange
::
MBExchange
(
UniSetTypes
::
ObjectId
objId
,
UniSetTypes
::
ObjectId
shmId
,
SharedMemory
*
ic
,
const
std
::
string
prefix
)
:
UniSetObject_LT
(
objId
),
allInitOK
(
false
),
shm
(
0
),
initPause
(
0
),
force
(
false
),
force_out
(
false
),
mbregFromID
(
false
),
sidExchangeMode
(
DefaultObjectId
),
activated
(
false
),
noQueryOptimization
(
false
),
no_extimer
(
false
),
prefix
(
prefix
),
poll_count
(
0
),
prop_prefix
(
""
),
mb
(
0
),
pollActivated
(
false
)
{
// cout << "$ $" << endl;
if
(
objId
==
DefaultObjectId
)
throw
UniSetTypes
::
SystemError
(
"(MBExchange): objId=-1?!! Use --"
+
prefix
+
"-name"
);
// xmlNode* cnode = conf->getNode(myname);
string
conf_name
=
conf
->
getArgParam
(
"--"
+
prefix
+
"-confnode"
,
myname
);
cnode
=
conf
->
getNode
(
conf_name
);
if
(
cnode
==
NULL
)
throw
UniSetTypes
::
SystemError
(
"(MBExchange): Not found node <"
+
conf_name
+
" ...> for "
+
myname
);
shm
=
new
SMInterface
(
shmId
,
&
ui
,
objId
,
ic
);
UniXML_iterator
it
(
cnode
);
// определяем фильтр
s_field
=
conf
->
getArgParam
(
"--"
+
prefix
+
"-filter-field"
);
s_fvalue
=
conf
->
getArgParam
(
"--"
+
prefix
+
"-filter-value"
);
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(init): read fileter-field='"
<<
s_field
<<
"' filter-value='"
<<
s_fvalue
<<
"'"
<<
endl
;
stat_time
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-statistic-sec"
,
it
.
getProp
(
"statistic_sec"
),
0
);
if
(
stat_time
>
0
)
ptStatistic
.
setTiming
(
stat_time
*
1000
);
// recv_timeout = conf->getArgPInt("--" + prefix + "-recv-timeout",it.getProp("recv_timeout"), 500);
//
// int tout = conf->getArgPInt("--" + prefix + "-timeout",it.getProp("timeout"), 5000);
// ptTimeout.setTiming(tout);
noQueryOptimization
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-no-query-optimization"
,
it
.
getProp
(
"no_query_optimization"
));
mbregFromID
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-reg-from-id"
,
it
.
getProp
(
"reg_from_id"
));
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(init): mbregFromID="
<<
mbregFromID
<<
endl
;
polltime
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-polltime"
,
it
.
getProp
(
"polltime"
),
100
);
initPause
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-initPause"
,
it
.
getProp
(
"initPause"
),
3000
);
sleepPause_usec
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-sleepPause-usec"
,
it
.
getProp
(
"slepePause"
),
100
);
force
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-force"
,
it
.
getProp
(
"force"
));
force_out
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-force-out"
,
it
.
getProp
(
"force_out"
));
// ********** HEARTBEAT *************
string
heart
=
conf
->
getArgParam
(
"--"
+
prefix
+
"-heartbeat-id"
,
it
.
getProp
(
"heartbeat_id"
));
if
(
!
heart
.
empty
()
)
{
sidHeartBeat
=
conf
->
getSensorID
(
heart
);
if
(
sidHeartBeat
==
DefaultObjectId
)
{
ostringstream
err
;
err
<<
myname
<<
": ID not found ('HeartBeat') for "
<<
heart
;
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(init): "
<<
err
.
str
()
<<
endl
;
throw
SystemError
(
err
.
str
());
}
int
heartbeatTime
=
getHeartBeatTime
();
if
(
heartbeatTime
)
ptHeartBeat
.
setTiming
(
heartbeatTime
);
else
ptHeartBeat
.
setTiming
(
UniSetTimer
::
WaitUpTime
);
maxHeartBeat
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-heartbeat-max"
,
it
.
getProp
(
"heartbeat_max"
),
10
);
test_id
=
sidHeartBeat
;
}
else
{
test_id
=
conf
->
getSensorID
(
"TestMode_S"
);
if
(
test_id
==
DefaultObjectId
)
{
ostringstream
err
;
err
<<
myname
<<
"(init): test_id unknown. 'TestMode_S' not found..."
;
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(init): "
<<
err
.
str
()
<<
endl
;
throw
SystemError
(
err
.
str
());
}
}
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(init): test_id="
<<
test_id
<<
endl
;
string
emode
=
conf
->
getArgParam
(
"--"
+
prefix
+
"-exchange-mode-id"
,
it
.
getProp
(
"exchangeModeID"
));
if
(
!
emode
.
empty
()
)
{
sidExchangeMode
=
conf
->
getSensorID
(
emode
);
if
(
sidExchangeMode
==
DefaultObjectId
)
{
ostringstream
err
;
err
<<
myname
<<
": ID not found ('ExchangeMode') for "
<<
emode
;
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(init): "
<<
err
.
str
()
<<
endl
;
throw
SystemError
(
err
.
str
());
}
}
activateTimeout
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-activate-timeout"
,
20000
);
}
// -----------------------------------------------------------------------------
void
MBExchange
::
help_print
(
int
argc
,
const
char
*
const
*
argv
)
{
cout
<<
"--prefix-name name - ObjectId (имя) процесса. По умолчанию: MBExchange1"
<<
endl
;
cout
<<
"--prefix-confnode name - Настроечная секция в конф. файле <name>. "
<<
endl
;
cout
<<
"--prefix-polltime msec - Пауза между опросаом карт. По умолчанию 200 мсек."
<<
endl
;
cout
<<
"--prefix-heartbeat-id name - Данный процесс связан с указанным аналоговым heartbeat-дачиком."
<<
endl
;
cout
<<
"--prefix-heartbeat-max val - Максимальное значение heartbeat-счётчика для данного процесса. По умолчанию 10."
<<
endl
;
cout
<<
"--prefix-ready-timeout msec - Время ожидания готовности SM к работе, мсек. (-1 - ждать 'вечно')"
<<
endl
;
cout
<<
"--prefix-force 0,1 - Сохранять значения в SM, независимо от, того менялось ли значение"
<<
endl
;
cout
<<
"--prefix-force-out 0,1 - Считывать значения 'выходов' кажый раз SM (а не по изменению)"
<<
endl
;
cout
<<
"--prefix-initPause msec - Задержка перед инициализацией (время на активизация процесса)"
<<
endl
;
cout
<<
"--prefix-no-query-optimization 0,1 - Не оптимизировать запросы (не объединять соседние регистры в один запрос)"
<<
endl
;
cout
<<
"--prefix-reg-from-id 0,1 - Использовать в качестве регистра sensor ID"
<<
endl
;
cout
<<
"--prefix-filter-field name - Считывать список опрашиваемых датчиков, только у которых есть поле field"
<<
endl
;
cout
<<
"--prefix-filter-value val - Считывать список опрашиваемых датчиков, только у которых field=value"
<<
endl
;
cout
<<
"--prefix-statistic-sec sec - Выводить статистику опроса каждые sec секунд"
<<
endl
;
cout
<<
"--prefix-sm-ready-timeout - время на ожидание старта SM"
<<
endl
;
}
// -----------------------------------------------------------------------------
MBExchange
::~
MBExchange
()
{
delete
shm
;
}
// -----------------------------------------------------------------------------
void
MBExchange
::
waitSMReady
()
{
// waiting for SM is ready...
int
ready_timeout
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-sm-ready-timeout"
,
"15000"
);
if
(
ready_timeout
==
0
)
ready_timeout
=
15000
;
else
if
(
ready_timeout
<
0
)
ready_timeout
=
UniSetTimer
::
WaitUpTime
;
if
(
!
shm
->
waitSMready
(
ready_timeout
,
50
)
)
{
ostringstream
err
;
err
<<
myname
<<
"(waitSMReady): failed waiting SharedMemory "
<<
ready_timeout
<<
" msec"
;
dlog
[
Debug
::
CRIT
]
<<
err
.
str
()
<<
endl
;
throw
SystemError
(
err
.
str
());
}
}
// -----------------------------------------------------------------------------
void
MBExchange
::
step
()
{
if
(
!
checkProcActive
()
)
return
;
if
(
sidHeartBeat
!=
DefaultObjectId
&&
ptHeartBeat
.
checkTime
()
)
{
try
{
shm
->
localSaveValue
(
aitHeartBeat
,
sidHeartBeat
,
maxHeartBeat
,
getId
());
ptHeartBeat
.
reset
();
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(step): (hb) "
<<
ex
<<
std
::
endl
;
}
}
}
// -----------------------------------------------------------------------------
bool
MBExchange
::
checkProcActive
()
{
uniset_mutex_lock
l
(
actMutex
,
300
);
return
activated
;
}
// -----------------------------------------------------------------------------
void
MBExchange
::
setProcActive
(
bool
st
)
{
uniset_mutex_lock
l
(
actMutex
,
400
);
activated
=
st
;
}
// -----------------------------------------------------------------------------
void
MBExchange
::
sigterm
(
int
signo
)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
": ********* SIGTERM("
<<
signo
<<
") ********"
<<
endl
;
setProcActive
(
false
);
UniSetObject_LT
::
sigterm
(
signo
);
}
// ------------------------------------------------------------------------------------------
void
MBExchange
::
readConfiguration
()
{
// readconf_ok = false;
xmlNode
*
root
=
conf
->
getXMLSensorsSection
();
if
(
!
root
)
{
ostringstream
err
;
err
<<
myname
<<
"(readConfiguration): не нашли корневого раздела <sensors>"
;
throw
SystemError
(
err
.
str
());
}
UniXML_iterator
it
(
root
);
if
(
!
it
.
goChildren
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(readConfiguration): раздел <sensors> не содержит секций ?!!
\n
"
;
return
;
}
for
(
;
it
.
getCurrent
();
it
.
goNext
()
)
{
if
(
UniSetTypes
::
check_filter
(
it
,
s_field
,
s_fvalue
)
)
initItem
(
it
);
}
// readconf_ok = true;
}
// ------------------------------------------------------------------------------------------
bool
MBExchange
::
readItem
(
UniXML
&
xml
,
UniXML_iterator
&
it
,
xmlNode
*
sec
)
{
if
(
UniSetTypes
::
check_filter
(
it
,
s_field
,
s_fvalue
)
)
initItem
(
it
);
return
true
;
}
// ------------------------------------------------------------------------------------------
MBExchange
::
DeviceType
MBExchange
::
getDeviceType
(
const
std
::
string
dtype
)
{
if
(
dtype
.
empty
()
)
return
dtUnknown
;
if
(
dtype
==
"mtr"
||
dtype
==
"MTR"
)
return
dtMTR
;
if
(
dtype
==
"rtu"
||
dtype
==
"RTU"
)
return
dtRTU
;
return
dtUnknown
;
}
// ------------------------------------------------------------------------------------------
void
MBExchange
::
initIterators
()
{
shm
->
initAIterator
(
aitHeartBeat
);
shm
->
initAIterator
(
aitExchangeMode
);
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
shm
->
initDIterator
(
d
->
resp_dit
);
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
for
(
PList
::
iterator
it2
=
it
->
second
->
slst
.
begin
();
it2
!=
it
->
second
->
slst
.
end
();
++
it2
)
{
shm
->
initDIterator
(
it2
->
dit
);
shm
->
initAIterator
(
it2
->
ait
);
}
}
}
}
// -----------------------------------------------------------------------------
bool
MBExchange
::
checkUpdateSM
(
bool
wrFunc
)
{
if
(
wrFunc
&&
exchangeMode
==
emReadOnly
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
"(checkUpdateSM):"
<<
" skip... mode='emReadOnly' "
<<
endl
;
return
false
;
}
if
(
!
wrFunc
&&
exchangeMode
==
emWriteOnly
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
"(checkUpdateSM):"
<<
" skip... mode='emWriteOnly' "
<<
endl
;
return
false
;
}
if
(
wrFunc
&&
exchangeMode
==
emSkipSaveToSM
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
"(checkUpdateSM):"
<<
" skip... mode='emSkipSaveToSM' "
<<
endl
;
return
false
;
}
return
true
;
}
// -----------------------------------------------------------------------------
bool
MBExchange
::
checkPoll
(
bool
wrFunc
)
{
if
(
exchangeMode
==
emWriteOnly
&&
!
wrFunc
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(checkPoll): skip.. mode='emWriteOnly'"
<<
endl
;
return
false
;
}
if
(
exchangeMode
==
emReadOnly
&&
wrFunc
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(checkPoll): skip.. poll mode='emReadOnly'"
<<
endl
;
return
false
;
}
return
true
;
}
// -----------------------------------------------------------------------------
MBExchange
::
RegID
MBExchange
::
genRegID
(
const
ModbusRTU
::
ModbusData
mbreg
,
const
int
fn
)
{
// формула для вычисления ID
// требования:
// 1. ID > диапазона возможных регистров
// 2. одинаковые регистры, но разные функции должны давать разный ID
// 3. регистры идущие подряд, должна давать ID идущие тоже подряд
// Вообще диапазоны:
// mbreg: 0..65535
// fn: 0...255
int
max
=
numeric_limits
<
ModbusRTU
::
ModbusData
>::
max
();
// по идее 65535
int
fn_max
=
numeric_limits
<
ModbusRTU
::
ModbusByte
>::
max
();
// по идее 255
// fn необходимо привести к диапазону 0..max
return
max
+
mbreg
+
max
+
UniSetTypes
::
lcalibrate
(
fn
,
0
,
fn_max
,
0
,
max
,
false
);
}
// ------------------------------------------------------------------------------------------
void
MBExchange
::
printMap
(
MBExchange
::
RTUDeviceMap
&
m
)
{
cout
<<
"devices: "
<<
endl
;
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it
=
m
.
begin
();
it
!=
m
.
end
();
++
it
)
{
cout
<<
" "
<<
*
(
it
->
second
)
<<
endl
;
}
}
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
MBExchange
::
RTUDeviceMap
&
m
)
{
os
<<
"devices: "
<<
endl
;
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it
=
m
.
begin
();
it
!=
m
.
end
();
++
it
)
{
os
<<
" "
<<
*
(
it
->
second
)
<<
endl
;
}
return
os
;
}
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
MBExchange
::
RTUDevice
&
d
)
{
os
<<
"addr="
<<
ModbusRTU
::
addr2str
(
d
.
mbaddr
)
<<
" type="
<<
d
.
dtype
<<
" respond_id="
<<
d
.
resp_id
<<
" respond_timeout="
<<
d
.
resp_ptTimeout
.
getInterval
()
<<
" respond_state="
<<
d
.
resp_state
<<
" respond_invert="
<<
d
.
resp_invert
<<
endl
;
os
<<
" regs: "
<<
endl
;
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
.
regmap
.
begin
();
it
!=
d
.
regmap
.
end
();
++
it
)
os
<<
" "
<<
*
(
it
->
second
)
<<
endl
;
return
os
;
}
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
MBExchange
::
RegInfo
&
r
)
{
os
<<
" id="
<<
r
.
id
<<
" mbreg="
<<
ModbusRTU
::
dat2str
(
r
.
mbreg
)
<<
" mbfunc="
<<
r
.
mbfunc
<<
" q_num="
<<
r
.
q_num
<<
" q_count="
<<
r
.
q_count
<<
" value="
<<
ModbusRTU
::
dat2str
(
r
.
mbval
)
<<
"("
<<
(
int
)
r
.
mbval
<<
")"
<<
" mtrType="
<<
MTR
::
type2str
(
r
.
mtrType
)
<<
endl
;
for
(
MBExchange
::
PList
::
iterator
it
=
r
.
slst
.
begin
();
it
!=
r
.
slst
.
end
();
++
it
)
os
<<
" "
<<
(
*
it
)
<<
endl
;
return
os
;
}
// -----------------------------------------------------------------------------
void
MBExchange
::
rtuQueryOptimization
(
RTUDeviceMap
&
m
)
{
if
(
noQueryOptimization
)
return
;
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(rtuQueryOptimization): optimization..."
<<
endl
;
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
m
.
begin
();
it1
!=
m
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
// Вообще в map они уже лежат в нужном порядке, т.е. функция genRegID() гарантирует
// что регистры идущие подряд с одниковой функцией чтения/записи получат подряд идущие ID.
// так что оптимтизация это просто нахождение мест где id идут не подряд...
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
MBExchange
::
RegMap
::
iterator
beg
=
it
;
RegID
id
=
it
->
second
->
id
;
// или собственно it->first
beg
->
second
->
q_num
=
1
;
beg
->
second
->
q_count
=
1
;
it
++
;
for
(
;
it
!=
d
->
regmap
.
end
();
++
it
)
{
if
(
(
it
->
second
->
id
-
id
)
>
1
)
{
it
--
;
// раз это регистр уже следующий, то надо вернуть на шаг обратно..
break
;
}
beg
->
second
->
q_count
++
;
if
(
beg
->
second
->
q_count
>=
ModbusRTU
::
MAXDATALEN
)
break
;
id
=
it
->
second
->
id
;
it
->
second
->
q_num
=
beg
->
second
->
q_count
;
it
->
second
->
q_count
=
0
;
}
// check correct function...
if
(
beg
->
second
->
q_count
>
1
&&
beg
->
second
->
mbfunc
==
ModbusRTU
::
fnWriteOutputSingleRegister
)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(rtuQueryOptimization): "
<<
" optimization change func="
<<
ModbusRTU
::
fnWriteOutputSingleRegister
<<
" <--> func="
<<
ModbusRTU
::
fnWriteOutputRegisters
<<
" for mbaddr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" mbreg="
<<
ModbusRTU
::
dat2str
(
beg
->
second
->
mbreg
);
beg
->
second
->
mbfunc
=
ModbusRTU
::
fnWriteOutputRegisters
;
}
else
if
(
beg
->
second
->
q_count
>
1
&&
beg
->
second
->
mbfunc
==
ModbusRTU
::
fnForceSingleCoil
)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(rtuQueryOptimization): "
<<
" optimization change func="
<<
ModbusRTU
::
fnForceSingleCoil
<<
" <--> func="
<<
ModbusRTU
::
fnForceMultipleCoils
<<
" for mbaddr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" mbreg="
<<
ModbusRTU
::
dat2str
(
beg
->
second
->
mbreg
);
beg
->
second
->
mbfunc
=
ModbusRTU
::
fnForceMultipleCoils
;
}
if
(
it
==
d
->
regmap
.
end
()
)
break
;
}
}
}
// -----------------------------------------------------------------------------
//std::ostream& operator<<( std::ostream& os, MBExchange::PList& lst )
std
::
ostream
&
MBExchange
::
print_plist
(
std
::
ostream
&
os
,
MBExchange
::
PList
&
lst
)
{
os
<<
"[ "
;
for
(
MBExchange
::
PList
::
const_iterator
it
=
lst
.
begin
();
it
!=
lst
.
end
();
++
it
)
os
<<
"("
<<
it
->
si
.
id
<<
")"
<<
conf
->
oind
->
getBaseName
(
conf
->
oind
->
getMapName
(
it
->
si
.
id
))
<<
" "
;
os
<<
"]"
;
return
os
;
}
// -----------------------------------------------------------------------------
void
MBExchange
::
firstInitRegisters
()
{
// если все вернут TRUE, значит OK.
allInitOK
=
true
;
for
(
InitList
::
iterator
it
=
initRegList
.
begin
();
it
!=
initRegList
.
end
();
++
it
)
{
try
{
it
->
initOK
=
preInitRead
(
it
);
allInitOK
=
it
->
initOK
;
}
catch
(
ModbusRTU
::
mbException
&
ex
)
{
allInitOK
=
false
;
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(preInitRead): FAILED ask addr="
<<
ModbusRTU
::
addr2str
(
it
->
dev
->
mbaddr
)
<<
" reg="
<<
ModbusRTU
::
dat2str
(
it
->
mbreg
)
<<
" err: "
<<
ex
<<
endl
;
}
if
(
!
it
->
dev
->
ask_every_reg
)
break
;
}
}
}
// -----------------------------------------------------------------------------
bool
MBExchange
::
preInitRead
(
InitList
::
iterator
&
p
)
{
if
(
p
->
initOK
)
return
true
;
RTUDevice
*
dev
=
p
->
dev
;
int
q_count
=
p
->
p
.
rnum
;
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(preInitRead): poll "
<<
" mbaddr="
<<
ModbusRTU
::
addr2str
(
dev
->
mbaddr
)
<<
" mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" mbfunc="
<<
p
->
mbfunc
<<
" q_count="
<<
q_count
<<
endl
;
if
(
q_count
>
ModbusRTU
::
MAXDATALEN
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(preInitRead): count("
<<
q_count
<<
") > MAXDATALEN("
<<
ModbusRTU
::
MAXDATALEN
<<
" ..ignore..."
<<
endl
;
}
}
switch
(
p
->
mbfunc
)
{
case
ModbusRTU
:
:
fnReadOutputRegisters
:
{
ModbusRTU
::
ReadOutputRetMessage
ret
=
mb
->
read03
(
dev
->
mbaddr
,
p
->
mbreg
,
q_count
);
p
->
initOK
=
initSMValue
(
ret
.
data
,
ret
.
count
,
&
(
p
->
p
));
}
break
;
case
ModbusRTU
:
:
fnReadInputRegisters
:
{
ModbusRTU
::
ReadInputRetMessage
ret1
=
mb
->
read04
(
dev
->
mbaddr
,
p
->
mbreg
,
q_count
);
p
->
initOK
=
initSMValue
(
ret1
.
data
,
ret1
.
count
,
&
(
p
->
p
));
}
break
;
case
ModbusRTU
:
:
fnReadInputStatus
:
{
ModbusRTU
::
ReadInputStatusRetMessage
ret
=
mb
->
read02
(
dev
->
mbaddr
,
p
->
mbreg
,
q_count
);
ModbusRTU
::
ModbusData
*
dat
=
new
ModbusRTU
::
ModbusData
[
q_count
];
int
m
=
0
;
for
(
int
i
=
0
;
i
<
ret
.
bcnt
;
i
++
)
{
ModbusRTU
::
DataBits
b
(
ret
.
data
[
i
]);
for
(
int
k
=
0
;
k
<
ModbusRTU
::
BitsPerByte
&&
m
<
q_count
;
k
++
,
m
++
)
dat
[
m
]
=
b
[
k
];
}
p
->
initOK
=
initSMValue
(
dat
,
q_count
,
&
(
p
->
p
));
delete
[]
dat
;
}
break
;
case
ModbusRTU
:
:
fnReadCoilStatus
:
{
ModbusRTU
::
ReadCoilRetMessage
ret
=
mb
->
read01
(
dev
->
mbaddr
,
p
->
mbreg
,
q_count
);
ModbusRTU
::
ModbusData
*
dat
=
new
ModbusRTU
::
ModbusData
[
q_count
];
int
m
=
0
;
for
(
int
i
=
0
;
i
<
ret
.
bcnt
;
i
++
)
{
ModbusRTU
::
DataBits
b
(
ret
.
data
[
i
]);
for
(
int
k
=
0
;
k
<
ModbusRTU
::
BitsPerByte
&&
m
<
q_count
;
k
++
,
m
++
)
dat
[
m
]
=
b
[
k
];
}
p
->
initOK
=
initSMValue
(
dat
,
q_count
,
&
(
p
->
p
));
delete
[]
dat
;
}
break
;
default
:
p
->
initOK
=
false
;
break
;
}
if
(
p
->
initOK
)
{
bool
f_out
=
force_out
;
// выставляем флаг принудительного обновления
force_out
=
true
;
p
->
ri
->
mb_initOK
=
true
;
p
->
ri
->
sm_initOK
=
false
;
updateRTU
(
p
->
ri
->
rit
);
force_out
=
f_out
;
}
return
p
->
initOK
;
}
// -----------------------------------------------------------------------------
bool
MBExchange
::
initSMValue
(
ModbusRTU
::
ModbusData
*
data
,
int
count
,
RSProperty
*
p
)
{
using
namespace
ModbusRTU
;
try
{
if
(
p
->
vType
==
VTypes
::
vtUnknown
)
{
ModbusRTU
::
DataBits16
b
(
data
[
0
]);
if
(
p
->
nbit
>=
0
)
{
bool
set
=
b
[
p
->
nbit
];
IOBase
::
processingAsDI
(
p
,
set
,
shm
,
force
);
return
true
;
}
if
(
p
->
rnum
<=
1
)
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
IOBase
::
processingAsDI
(
p
,
data
[
0
],
shm
,
force
);
}
else
IOBase
::
processingAsAI
(
p
,
(
signed
short
)(
data
[
0
]),
shm
,
force
);
return
true
;
}
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initSMValue): IGNORE item: rnum="
<<
p
->
rnum
<<
" > 1 ?!! for id="
<<
p
->
si
.
id
<<
endl
;
return
false
;
}
else
if
(
p
->
vType
==
VTypes
::
vtSigned
)
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
IOBase
::
processingAsDI
(
p
,
data
[
0
],
shm
,
force
);
}
else
IOBase
::
processingAsAI
(
p
,
(
signed
short
)(
data
[
0
]),
shm
,
force
);
return
true
;
}
else
if
(
p
->
vType
==
VTypes
::
vtUnsigned
)
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
IOBase
::
processingAsDI
(
p
,
data
[
0
],
shm
,
force
);
}
else
IOBase
::
processingAsAI
(
p
,
(
unsigned
short
)
data
[
0
],
shm
,
force
);
return
true
;
}
else
if
(
p
->
vType
==
VTypes
::
vtByte
)
{
if
(
p
->
nbyte
<=
0
||
p
->
nbyte
>
VTypes
::
Byte
::
bsize
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initSMValue): IGNORE item: sid="
<<
ModbusRTU
::
dat2str
(
p
->
si
.
id
)
<<
" vtype="
<<
p
->
vType
<<
" but nbyte="
<<
p
->
nbyte
<<
endl
;
return
false
;
}
VTypes
::
Byte
b
(
data
[
0
]);
IOBase
::
processingAsAI
(
p
,
b
.
raw
.
b
[
p
->
nbyte
-
1
],
shm
,
force
);
return
true
;
}
else
if
(
p
->
vType
==
VTypes
::
vtF2
)
{
VTypes
::
F2
f
(
data
,
VTypes
::
F2
::
wsize
());
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
force
);
}
else
if
(
p
->
vType
==
VTypes
::
vtF4
)
{
VTypes
::
F4
f
(
data
,
VTypes
::
F4
::
wsize
());
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
force
);
}
else
if
(
p
->
vType
==
VTypes
::
vtI2
)
{
VTypes
::
I2
i2
(
data
,
VTypes
::
I2
::
wsize
());
IOBase
::
processingAsAI
(
p
,
(
int
)
i2
,
shm
,
force
);
}
else
if
(
p
->
vType
==
VTypes
::
vtU2
)
{
VTypes
::
U2
u2
(
data
,
VTypes
::
U2
::
wsize
());
IOBase
::
processingAsAI
(
p
,
(
unsigned
int
)
u2
,
shm
,
force
);
}
return
true
;
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(initSMValue):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
catch
(
IOController_i
::
IOBadParam
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(initSMValue):(IOBadParam) "
<<
ex
.
err
<<
endl
;
}
catch
(
IONotifyController_i
::
BadRange
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(initSMValue): (BadRange)..."
<<
endl
;
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(initSMValue): "
<<
ex
<<
endl
;
}
catch
(
CORBA
::
SystemException
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(initSMValue): CORBA::SystemException: "
<<
ex
.
NP_minorString
()
<<
endl
;
}
catch
(...)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(initSMValue): catch ..."
<<
endl
;
}
return
false
;
}
// -----------------------------------------------------------------------------
bool
MBExchange
::
pollRTU
(
RTUDevice
*
dev
,
RegMap
::
iterator
&
it
)
{
RegInfo
*
p
(
it
->
second
);
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(pollRTU): poll "
<<
" mbaddr="
<<
ModbusRTU
::
addr2str
(
dev
->
mbaddr
)
<<
" mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" mbfunc="
<<
p
->
mbfunc
<<
" q_count="
<<
p
->
q_count
<<
" mb_initOK="
<<
p
->
mb_initOK
<<
" sm_initOK="
<<
p
->
sm_initOK
<<
" mbval="
<<
p
->
mbval
<<
endl
;
if
(
p
->
q_count
>
ModbusRTU
::
MAXDATALEN
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(pollRTU): count("
<<
p
->
q_count
<<
") > MAXDATALEN("
<<
ModbusRTU
::
MAXDATALEN
<<
" ..ignore..."
<<
endl
;
}
}
if
(
!
checkPoll
(
ModbusRTU
::
isWriteFunction
(
p
->
mbfunc
))
)
return
true
;
if
(
p
->
q_count
==
0
)
{
if
(
dlog
.
debugging
(
Debug
::
INFO
)
)
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(pollRTU): q_count=0 for mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" IGNORE register..."
<<
endl
;
return
false
;
}
switch
(
p
->
mbfunc
)
{
case
ModbusRTU
:
:
fnReadInputRegisters
:
{
ModbusRTU
::
ReadInputRetMessage
ret
=
mb
->
read04
(
dev
->
mbaddr
,
p
->
mbreg
,
p
->
q_count
);
for
(
int
i
=
0
;
i
<
p
->
q_count
;
i
++
,
it
++
)
it
->
second
->
mbval
=
ret
.
data
[
i
];
it
--
;
}
break
;
case
ModbusRTU
:
:
fnReadOutputRegisters
:
{
ModbusRTU
::
ReadOutputRetMessage
ret
=
mb
->
read03
(
dev
->
mbaddr
,
p
->
mbreg
,
p
->
q_count
);
for
(
int
i
=
0
;
i
<
p
->
q_count
;
i
++
,
it
++
)
it
->
second
->
mbval
=
ret
.
data
[
i
];
it
--
;
}
break
;
case
ModbusRTU
:
:
fnReadInputStatus
:
{
ModbusRTU
::
ReadInputStatusRetMessage
ret
=
mb
->
read02
(
dev
->
mbaddr
,
p
->
mbreg
,
p
->
q_count
);
int
m
=
0
;
for
(
int
i
=
0
;
i
<
ret
.
bcnt
;
i
++
)
{
ModbusRTU
::
DataBits
b
(
ret
.
data
[
i
]);
for
(
int
k
=
0
;
k
<
ModbusRTU
::
BitsPerByte
&&
m
<
p
->
q_count
;
k
++
,
it
++
,
m
++
)
it
->
second
->
mbval
=
b
[
k
];
}
it
--
;
}
break
;
case
ModbusRTU
:
:
fnReadCoilStatus
:
{
ModbusRTU
::
ReadCoilRetMessage
ret
=
mb
->
read01
(
dev
->
mbaddr
,
p
->
mbreg
,
p
->
q_count
);
int
m
=
0
;
for
(
int
i
=
0
;
i
<
ret
.
bcnt
;
i
++
)
{
ModbusRTU
::
DataBits
b
(
ret
.
data
[
i
]);
for
(
int
k
=
0
;
k
<
ModbusRTU
::
BitsPerByte
&&
m
<
p
->
q_count
;
k
++
,
it
++
,
m
++
)
it
->
second
->
mbval
=
b
[
k
]
?
1
:
0
;
}
it
--
;
}
break
;
case
ModbusRTU
:
:
fnWriteOutputSingleRegister
:
{
if
(
p
->
q_count
!=
1
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(pollRTU): mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" IGNORE WRITE SINGLE REGISTER (0x06) q_count="
<<
p
->
q_count
<<
" ..."
<<
endl
;
return
false
;
}
if
(
!
p
->
sm_initOK
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(pollRTU): mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" slist="
<<
(
*
p
)
<<
" IGNORE...(sm_initOK=false)"
<<
endl
;
return
true
;
}
// cerr << "**** mbreg=" << ModbusRTU::dat2str(p->mbreg) << " val=" << ModbusRTU::dat2str(p->mbval) << endl;
ModbusRTU
::
WriteSingleOutputRetMessage
ret
=
mb
->
write06
(
dev
->
mbaddr
,
p
->
mbreg
,
p
->
mbval
);
}
break
;
case
ModbusRTU
:
:
fnWriteOutputRegisters
:
{
if
(
!
p
->
sm_initOK
)
{
// может быть такая ситуация, что
// некоторые регистры уже инициализированы, а другие ещё нет
// при этом после оптимизации они попадают в один запрос
// поэтому здесь сделано так:
// если q_num > 1, значит этот регистр относится к предыдущему запросу
// и его просто надо пропустить..
if
(
p
->
q_num
>
1
)
return
true
;
// смещаем итератор, если данный запрос содержит много регистров
// if( q->count > 1 )
// {
// for( int i=0; i<p->q_count; i++ )
// it++;
// return true;
// }
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(pollRTU): mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" IGNORE...(sm_initOK=false)"
<<
endl
;
return
true
;
}
ModbusRTU
::
WriteOutputMessage
msg
(
dev
->
mbaddr
,
p
->
mbreg
);
for
(
int
i
=
0
;
i
<
p
->
q_count
;
i
++
,
it
++
)
msg
.
addData
(
it
->
second
->
mbval
);
it
--
;
ModbusRTU
::
WriteOutputRetMessage
ret
=
mb
->
write10
(
msg
);
}
break
;
case
ModbusRTU
:
:
fnForceSingleCoil
:
{
if
(
p
->
q_count
!=
1
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(pollRTU): mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" IGNORE FORCE SINGLE COIL (0x05) q_count="
<<
p
->
q_count
<<
" ..."
<<
endl
;
return
false
;
}
if
(
!
p
->
sm_initOK
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(pollRTU): mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" IGNORE...(sm_initOK=false)"
<<
endl
;
return
true
;
}
// cerr << "****(coil) mbreg=" << ModbusRTU::dat2str(p->mbreg) << " val=" << ModbusRTU::dat2str(p->mbval) << endl;
ModbusRTU
::
ForceSingleCoilRetMessage
ret
=
mb
->
write05
(
dev
->
mbaddr
,
p
->
mbreg
,
p
->
mbval
);
}
break
;
case
ModbusRTU
:
:
fnForceMultipleCoils
:
{
if
(
!
p
->
sm_initOK
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(pollRTU): mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" IGNORE...(sm_initOK=false)"
<<
endl
;
return
true
;
}
ModbusRTU
::
ForceCoilsMessage
msg
(
dev
->
mbaddr
,
p
->
mbreg
);
for
(
int
i
=
0
;
i
<
p
->
q_count
;
i
++
,
it
++
)
msg
.
addBit
(
(
it
->
second
->
mbval
?
true
:
false
)
);
it
--
;
// cerr << "*********** (write multiple): " << msg << endl;
ModbusRTU
::
ForceCoilsRetMessage
ret
=
mb
->
write0F
(
msg
);
}
break
;
default
:
{
if
(
dlog
.
debugging
(
Debug
::
WARN
)
)
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(pollRTU): mbreg="
<<
ModbusRTU
::
dat2str
(
p
->
mbreg
)
<<
" IGNORE mfunc="
<<
(
int
)
p
->
mbfunc
<<
" ..."
<<
endl
;
return
false
;
}
break
;
}
return
true
;
}
// -----------------------------------------------------------------------------
void
MBExchange
::
updateSM
()
{
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
// обновление датчиков связи происходит в другом потоке
// чтобы не зависеть от TCP таймаутов
// см. updateRespondSensors()
// update values...
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
try
{
if
(
d
->
dtype
==
dtRTU
)
updateRTU
(
it
);
else
if
(
d
->
dtype
==
dtMTR
)
updateMTR
(
it
);
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
catch
(
IOController_i
::
IOBadParam
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM):(IOBadParam) "
<<
ex
.
err
<<
endl
;
}
catch
(
IONotifyController_i
::
BadRange
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM): (BadRange)..."
<<
endl
;
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM): "
<<
ex
<<
endl
;
}
catch
(
CORBA
::
SystemException
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM): CORBA::SystemException: "
<<
ex
.
NP_minorString
()
<<
endl
;
}
catch
(...)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateSM): catch ..."
<<
endl
;
}
if
(
it
==
d
->
regmap
.
end
()
)
break
;
}
}
}
// -----------------------------------------------------------------------------
void
MBExchange
::
updateRTU
(
RegMap
::
iterator
&
rit
)
{
RegInfo
*
r
(
rit
->
second
);
for
(
PList
::
iterator
it
=
r
->
slst
.
begin
();
it
!=
r
->
slst
.
end
();
++
it
)
updateRSProperty
(
&
(
*
it
),
false
);
}
// -----------------------------------------------------------------------------
void
MBExchange
::
updateRSProperty
(
RSProperty
*
p
,
bool
write_only
)
{
using
namespace
ModbusRTU
;
RegInfo
*
r
(
p
->
reg
->
rit
->
second
);
bool
save
=
isWriteFunction
(
r
->
mbfunc
);
if
(
!
save
&&
write_only
)
return
;
if
(
!
checkUpdateSM
(
save
)
)
return
;
// если требуется инициализация и она ещё не произведена,
// то игнорируем
if
(
save
&&
!
r
->
mb_initOK
)
return
;
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
"updateP: sid="
<<
p
->
si
.
id
<<
" mbval="
<<
r
->
mbval
<<
" vtype="
<<
p
->
vType
<<
" rnum="
<<
p
->
rnum
<<
" nbit="
<<
p
->
nbit
<<
" save="
<<
save
<<
" ioype="
<<
p
->
stype
<<
" mb_initOK="
<<
r
->
mb_initOK
<<
" sm_initOK="
<<
r
->
sm_initOK
<<
endl
;
try
{
if
(
p
->
vType
==
VTypes
::
vtUnknown
)
{
ModbusRTU
::
DataBits16
b
(
r
->
mbval
);
if
(
p
->
nbit
>=
0
)
{
if
(
save
)
{
if
(
r
->
mb_initOK
)
{
bool
set
=
IOBase
::
processingAsDO
(
p
,
shm
,
force_out
);
b
.
set
(
p
->
nbit
,
set
);
r
->
mbval
=
b
.
mdata
();
r
->
sm_initOK
=
true
;
}
}
else
{
bool
set
=
b
[
p
->
nbit
];
IOBase
::
processingAsDI
(
p
,
set
,
shm
,
force
);
}
return
;
}
if
(
p
->
rnum
<=
1
)
{
if
(
save
)
{
if
(
r
->
mb_initOK
)
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
r
->
mbval
=
IOBase
::
processingAsDO
(
p
,
shm
,
force_out
);
}
else
r
->
mbval
=
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
r
->
sm_initOK
=
true
;
}
}
else
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
IOBase
::
processingAsDI
(
p
,
r
->
mbval
,
shm
,
force
);
}
else
IOBase
::
processingAsAI
(
p
,
(
signed
short
)(
r
->
mbval
),
shm
,
force
);
}
return
;
}
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(updateRSProperty): IGNORE item: rnum="
<<
p
->
rnum
<<
" > 1 ?!! for id="
<<
p
->
si
.
id
<<
endl
;
return
;
}
else
if
(
p
->
vType
==
VTypes
::
vtSigned
)
{
if
(
save
)
{
if
(
r
->
mb_initOK
)
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
r
->
mbval
=
(
signed
short
)
IOBase
::
processingAsDO
(
p
,
shm
,
force_out
);
}
else
r
->
mbval
=
(
signed
short
)
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
r
->
sm_initOK
=
true
;
}
}
else
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
IOBase
::
processingAsDI
(
p
,
r
->
mbval
,
shm
,
force
);
}
else
{
IOBase
::
processingAsAI
(
p
,
(
signed
short
)(
r
->
mbval
),
shm
,
force
);
}
}
return
;
}
else
if
(
p
->
vType
==
VTypes
::
vtUnsigned
)
{
if
(
save
)
{
if
(
r
->
mb_initOK
)
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
r
->
mbval
=
(
unsigned
short
)
IOBase
::
processingAsDO
(
p
,
shm
,
force_out
);
}
else
r
->
mbval
=
(
unsigned
short
)
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
r
->
sm_initOK
=
true
;
}
}
else
{
if
(
p
->
stype
==
UniversalIO
::
DigitalInput
||
p
->
stype
==
UniversalIO
::
DigitalOutput
)
{
IOBase
::
processingAsDI
(
p
,
r
->
mbval
,
shm
,
force
);
}
else
{
IOBase
::
processingAsAI
(
p
,
(
unsigned
short
)
r
->
mbval
,
shm
,
force
);
}
}
return
;
}
else
if
(
p
->
vType
==
VTypes
::
vtByte
)
{
if
(
p
->
nbyte
<=
0
||
p
->
nbyte
>
VTypes
::
Byte
::
bsize
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(updateRSProperty): IGNORE item: reg="
<<
ModbusRTU
::
dat2str
(
r
->
mbreg
)
<<
" vtype="
<<
p
->
vType
<<
" but nbyte="
<<
p
->
nbyte
<<
endl
;
return
;
}
if
(
save
&&
r
->
sm_initOK
)
{
if
(
r
->
mb_initOK
)
{
long
v
=
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
VTypes
::
Byte
b
(
r
->
mbval
);
b
.
raw
.
b
[
p
->
nbyte
-
1
]
=
v
;
r
->
mbval
=
b
.
raw
.
w
;
r
->
sm_initOK
=
true
;
}
}
else
{
VTypes
::
Byte
b
(
r
->
mbval
);
IOBase
::
processingAsAI
(
p
,
b
.
raw
.
b
[
p
->
nbyte
-
1
],
shm
,
force
);
}
return
;
}
else
if
(
p
->
vType
==
VTypes
::
vtF2
)
{
RegMap
::
iterator
i
(
p
->
reg
->
rit
);
if
(
save
)
{
if
(
r
->
mb_initOK
)
{
float
f
=
IOBase
::
processingFasAO
(
p
,
shm
,
force_out
);
VTypes
::
F2
f2
(
f
);
for
(
int
k
=
0
;
k
<
VTypes
::
F2
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
f2
.
raw
.
v
[
k
];
r
->
sm_initOK
=
true
;
}
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
VTypes
::
F2
::
wsize
()];
for
(
int
k
=
0
;
k
<
VTypes
::
F2
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
VTypes
::
F2
f
(
data
,
VTypes
::
F2
::
wsize
());
delete
[]
data
;
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
force
);
}
}
else
if
(
p
->
vType
==
VTypes
::
vtF4
)
{
RegMap
::
iterator
i
(
p
->
reg
->
rit
);
if
(
save
)
{
if
(
r
->
mb_initOK
)
{
float
f
=
IOBase
::
processingFasAO
(
p
,
shm
,
force_out
);
VTypes
::
F4
f4
(
f
);
for
(
int
k
=
0
;
k
<
VTypes
::
F4
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
f4
.
raw
.
v
[
k
];
}
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
VTypes
::
F4
::
wsize
()];
for
(
int
k
=
0
;
k
<
VTypes
::
F4
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
VTypes
::
F4
f
(
data
,
VTypes
::
F4
::
wsize
());
delete
[]
data
;
IOBase
::
processingFasAI
(
p
,
(
float
)
f
,
shm
,
force
);
}
}
else
if
(
p
->
vType
==
VTypes
::
vtI2
)
{
RegMap
::
iterator
i
(
p
->
reg
->
rit
);
if
(
save
)
{
if
(
r
->
mb_initOK
)
{
long
v
=
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
VTypes
::
I2
i2
(
v
);
for
(
int
k
=
0
;
k
<
VTypes
::
I2
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
i2
.
raw
.
v
[
k
];
r
->
sm_initOK
=
true
;
}
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
VTypes
::
I2
::
wsize
()];
for
(
int
k
=
0
;
k
<
VTypes
::
I2
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
VTypes
::
I2
i2
(
data
,
VTypes
::
I2
::
wsize
());
delete
[]
data
;
IOBase
::
processingAsAI
(
p
,
(
int
)
i2
,
shm
,
force
);
}
}
else
if
(
p
->
vType
==
VTypes
::
vtU2
)
{
RegMap
::
iterator
i
(
p
->
reg
->
rit
);
if
(
save
)
{
if
(
r
->
mb_initOK
)
{
long
v
=
IOBase
::
processingAsAO
(
p
,
shm
,
force_out
);
VTypes
::
U2
u2
(
v
);
for
(
int
k
=
0
;
k
<
VTypes
::
U2
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
u2
.
raw
.
v
[
k
];
r
->
sm_initOK
=
true
;
}
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
VTypes
::
U2
::
wsize
()];
for
(
int
k
=
0
;
k
<
VTypes
::
U2
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
VTypes
::
U2
u2
(
data
,
VTypes
::
U2
::
wsize
());
delete
[]
data
;
IOBase
::
processingAsAI
(
p
,
(
unsigned
int
)
u2
,
shm
,
force
);
}
}
return
;
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
catch
(
IOController_i
::
IOBadParam
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty):(IOBadParam) "
<<
ex
.
err
<<
endl
;
}
catch
(
IONotifyController_i
::
BadRange
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty): (BadRange)..."
<<
endl
;
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty): "
<<
ex
<<
endl
;
}
catch
(
CORBA
::
SystemException
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty): CORBA::SystemException: "
<<
ex
.
NP_minorString
()
<<
endl
;
}
catch
(...)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateRSProperty): catch ..."
<<
endl
;
}
// Если SM стала (или была) недоступна
// то флаг инициализации надо сбросить
r
->
sm_initOK
=
false
;
}
// -----------------------------------------------------------------------------
void
MBExchange
::
updateMTR
(
RegMap
::
iterator
&
rit
)
{
RegInfo
*
r
(
rit
->
second
);
using
namespace
ModbusRTU
;
bool
save
=
isWriteFunction
(
r
->
mbfunc
);
if
(
save
&&
exchangeMode
==
emReadOnly
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR):"
<<
" skip... mode=emReadOnly "
<<
endl
;
return
;
}
if
(
!
save
&&
exchangeMode
==
emWriteOnly
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR):"
<<
" skip... mode=emWriteOnly "
<<
endl
;
return
;
}
if
(
save
&&
exchangeMode
==
emSkipSaveToSM
)
{
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR):"
<<
" skip... mode=emSkipSaveToSM "
<<
endl
;
return
;
}
{
for
(
PList
::
iterator
it
=
r
->
slst
.
begin
();
it
!=
r
->
slst
.
end
();
++
it
)
{
try
{
if
(
r
->
mtrType
==
MTR
::
mtT1
)
{
if
(
save
)
r
->
mbval
=
IOBase
::
processingAsAO
(
&
(
*
it
),
shm
,
force_out
);
else
{
MTR
::
T1
t
(
r
->
mbval
);
IOBase
::
processingAsAI
(
&
(
*
it
),
t
.
val
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT2
)
{
if
(
save
)
{
MTR
::
T2
t
(
IOBase
::
processingAsAO
(
&
(
*
it
),
shm
,
force_out
));
r
->
mbval
=
t
.
val
;
}
else
{
MTR
::
T2
t
(
r
->
mbval
);
IOBase
::
processingAsAI
(
&
(
*
it
),
t
.
val
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT3
)
{
RegMap
::
iterator
i
(
rit
);
if
(
save
)
{
MTR
::
T3
t
(
IOBase
::
processingAsAO
(
&
(
*
it
),
shm
,
force_out
));
for
(
int
k
=
0
;
k
<
MTR
::
T3
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
t
.
raw
.
v
[
k
];
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
MTR
::
T3
::
wsize
()];
for
(
int
k
=
0
;
k
<
MTR
::
T3
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
MTR
::
T3
t
(
data
,
MTR
::
T3
::
wsize
());
delete
[]
data
;
IOBase
::
processingAsAI
(
&
(
*
it
),
(
long
)
t
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT4
)
{
if
(
save
)
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(updateMTR): write (T4) reg("
<<
dat2str
(
r
->
mbreg
)
<<
") to MTR NOT YET!!!"
<<
endl
;
else
{
MTR
::
T4
t
(
r
->
mbval
);
IOBase
::
processingAsAI
(
&
(
*
it
),
uni_atoi
(
t
.
sval
),
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT5
)
{
RegMap
::
iterator
i
(
rit
);
if
(
save
)
{
MTR
::
T5
t
(
IOBase
::
processingAsAO
(
&
(
*
it
),
shm
,
force_out
));
for
(
int
k
=
0
;
k
<
MTR
::
T5
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
t
.
raw
.
v
[
k
];
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
MTR
::
T5
::
wsize
()];
for
(
int
k
=
0
;
k
<
MTR
::
T5
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
MTR
::
T5
t
(
data
,
MTR
::
T5
::
wsize
());
delete
[]
data
;
IOBase
::
processingFasAI
(
&
(
*
it
),
(
float
)
t
.
val
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT6
)
{
RegMap
::
iterator
i
(
rit
);
if
(
save
)
{
MTR
::
T6
t
(
IOBase
::
processingAsAO
(
&
(
*
it
),
shm
,
force_out
));
for
(
int
k
=
0
;
k
<
MTR
::
T6
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
t
.
raw
.
v
[
k
];
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
MTR
::
T6
::
wsize
()];
for
(
int
k
=
0
;
k
<
MTR
::
T6
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
MTR
::
T6
t
(
data
,
MTR
::
T6
::
wsize
());
delete
[]
data
;
IOBase
::
processingFasAI
(
&
(
*
it
),
(
float
)
t
.
val
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT7
)
{
RegMap
::
iterator
i
(
rit
);
if
(
save
)
{
MTR
::
T7
t
(
IOBase
::
processingAsAO
(
&
(
*
it
),
shm
,
force_out
));
for
(
int
k
=
0
;
k
<
MTR
::
T7
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
t
.
raw
.
v
[
k
];
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
MTR
::
T7
::
wsize
()];
for
(
int
k
=
0
;
k
<
MTR
::
T7
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
MTR
::
T7
t
(
data
,
MTR
::
T7
::
wsize
());
delete
[]
data
;
IOBase
::
processingFasAI
(
&
(
*
it
),
(
float
)
t
.
val
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT16
)
{
if
(
save
)
{
MTR
::
T16
t
(
IOBase
::
processingFasAO
(
&
(
*
it
),
shm
,
force_out
));
r
->
mbval
=
t
.
val
;
}
else
{
MTR
::
T16
t
(
r
->
mbval
);
IOBase
::
processingFasAI
(
&
(
*
it
),
t
.
fval
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtT17
)
{
if
(
save
)
{
MTR
::
T17
t
(
IOBase
::
processingFasAO
(
&
(
*
it
),
shm
,
force_out
));
r
->
mbval
=
t
.
val
;
}
else
{
MTR
::
T17
t
(
r
->
mbval
);
IOBase
::
processingFasAI
(
&
(
*
it
),
t
.
fval
,
shm
,
force
);
}
continue
;
}
if
(
r
->
mtrType
==
MTR
::
mtF1
)
{
RegMap
::
iterator
i
(
rit
);
if
(
save
)
{
float
f
=
IOBase
::
processingFasAO
(
&
(
*
it
),
shm
,
force_out
);
MTR
::
F1
f1
(
f
);
for
(
int
k
=
0
;
k
<
MTR
::
F1
::
wsize
();
k
++
,
i
++
)
i
->
second
->
mbval
=
f1
.
raw
.
v
[
k
];
}
else
{
ModbusRTU
::
ModbusData
*
data
=
new
ModbusRTU
::
ModbusData
[
MTR
::
F1
::
wsize
()];
for
(
int
k
=
0
;
k
<
MTR
::
F1
::
wsize
();
k
++
,
i
++
)
data
[
k
]
=
i
->
second
->
mbval
;
MTR
::
F1
t
(
data
,
MTR
::
F1
::
wsize
());
delete
[]
data
;
IOBase
::
processingFasAI
(
&
(
*
it
),
(
float
)
t
,
shm
,
force
);
}
continue
;
}
}
catch
(
IOController_i
::
NameNotFound
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR):(NameNotFound) "
<<
ex
.
err
<<
endl
;
}
catch
(
IOController_i
::
IOBadParam
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR):(IOBadParam) "
<<
ex
.
err
<<
endl
;
}
catch
(
IONotifyController_i
::
BadRange
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR): (BadRange)..."
<<
endl
;
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR): "
<<
ex
<<
endl
;
}
catch
(
CORBA
::
SystemException
&
ex
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR): CORBA::SystemException: "
<<
ex
.
NP_minorString
()
<<
endl
;
}
catch
(...)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(updateMTR): catch ..."
<<
endl
;
}
}
}
}
// -----------------------------------------------------------------------------
MBExchange
::
RTUDevice
*
MBExchange
::
addDev
(
RTUDeviceMap
&
mp
,
ModbusRTU
::
ModbusAddr
a
,
UniXML_iterator
&
xmlit
)
{
RTUDeviceMap
::
iterator
it
=
mp
.
find
(
a
);
if
(
it
!=
mp
.
end
()
)
{
DeviceType
dtype
=
getDeviceType
(
xmlit
.
getProp
(
prop_prefix
+
"mbtype"
));
if
(
it
->
second
->
dtype
!=
dtype
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(addDev): OTHER mbtype="
<<
dtype
<<
" for "
<<
xmlit
.
getProp
(
"name"
)
<<
". Already used devtype="
<<
it
->
second
->
dtype
<<
" for mbaddr="
<<
ModbusRTU
::
addr2str
(
it
->
second
->
mbaddr
)
<<
endl
;
return
0
;
}
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(addDev): device for addr="
<<
ModbusRTU
::
addr2str
(
a
)
<<
" already added. Ignore device params for "
<<
xmlit
.
getProp
(
"name"
)
<<
" ..."
<<
endl
;
return
it
->
second
;
}
MBExchange
::
RTUDevice
*
d
=
new
MBExchange
::
RTUDevice
();
d
->
mbaddr
=
a
;
if
(
!
initRTUDevice
(
d
,
xmlit
)
)
{
delete
d
;
return
0
;
}
mp
.
insert
(
RTUDeviceMap
::
value_type
(
a
,
d
));
return
d
;
}
// ------------------------------------------------------------------------------------------
MBExchange
::
RegInfo
*
MBExchange
::
addReg
(
RegMap
&
mp
,
RegID
id
,
ModbusRTU
::
ModbusData
r
,
UniXML_iterator
&
xmlit
,
MBExchange
::
RTUDevice
*
dev
,
MBExchange
::
RegInfo
*
rcopy
)
{
RegMap
::
iterator
it
=
mp
.
find
(
id
);
if
(
it
!=
mp
.
end
()
)
{
if
(
!
it
->
second
->
dev
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(addReg): for "
<<
xmlit
.
getProp
(
"name"
)
<<
" dev=0!!!! "
<<
endl
;
return
0
;
}
if
(
it
->
second
->
dev
->
dtype
!=
dev
->
dtype
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(addReg): OTHER mbtype="
<<
dev
->
dtype
<<
" for "
<<
xmlit
.
getProp
(
"name"
)
<<
". Already used devtype="
<<
it
->
second
->
dev
->
dtype
<<
" for "
<<
it
->
second
->
dev
<<
endl
;
return
0
;
}
if
(
dlog
.
debugging
(
Debug
::
INFO
)
)
{
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(addReg): reg="
<<
ModbusRTU
::
dat2str
(
r
)
<<
"(id="
<<
id
<<
")"
<<
" already added for "
<<
(
*
it
->
second
)
<<
" Ignore register params for "
<<
xmlit
.
getProp
(
"name"
)
<<
" ..."
<<
endl
;
}
it
->
second
->
rit
=
it
;
return
it
->
second
;
}
MBExchange
::
RegInfo
*
ri
;
if
(
rcopy
)
{
ri
=
new
MBExchange
::
RegInfo
(
*
rcopy
);
ri
->
slst
.
clear
();
ri
->
mbreg
=
r
;
}
else
{
ri
=
new
MBExchange
::
RegInfo
();
if
(
!
initRegInfo
(
ri
,
xmlit
,
dev
)
)
{
delete
ri
;
return
0
;
}
ri
->
mbreg
=
r
;
}
ri
->
id
=
id
;
mp
.
insert
(
RegMap
::
value_type
(
id
,
ri
));
ri
->
rit
=
mp
.
find
(
id
);
return
ri
;
}
// ------------------------------------------------------------------------------------------
MBExchange
::
RSProperty
*
MBExchange
::
addProp
(
PList
&
plist
,
RSProperty
&
p
)
{
for
(
PList
::
iterator
it
=
plist
.
begin
();
it
!=
plist
.
end
();
++
it
)
{
if
(
it
->
si
.
id
==
p
.
si
.
id
&&
it
->
si
.
node
==
p
.
si
.
node
)
return
&
(
*
it
);
}
plist
.
push_back
(
p
);
PList
::
iterator
it
=
plist
.
end
();
it
--
;
return
&
(
*
it
);
}
// ------------------------------------------------------------------------------------------
bool
MBExchange
::
initRSProperty
(
RSProperty
&
p
,
UniXML_iterator
&
it
)
{
if
(
!
IOBase
::
initItem
(
&
p
,
it
,
shm
,
&
dlog
,
myname
)
)
return
false
;
if
(
it
.
getIntProp
(
prop_prefix
+
"rawdata"
)
)
{
p
.
cal
.
minRaw
=
0
;
p
.
cal
.
maxRaw
=
0
;
p
.
cal
.
minCal
=
0
;
p
.
cal
.
maxCal
=
0
;
p
.
cal
.
precision
=
0
;
p
.
cdiagram
=
0
;
}
string
stype
(
it
.
getProp
(
prop_prefix
+
"iotype"
)
);
if
(
!
stype
.
empty
()
)
{
p
.
stype
=
UniSetTypes
::
getIOType
(
stype
);
if
(
p
.
stype
==
UniversalIO
::
UnknownIOType
)
{
if
(
dlog
)
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(IOBase::readItem): неизвестный iotype=: "
<<
stype
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
}
string
sbit
(
it
.
getProp
(
prop_prefix
+
"nbit"
));
if
(
!
sbit
.
empty
()
)
{
p
.
nbit
=
UniSetTypes
::
uni_atoi
(
sbit
.
c_str
());
if
(
p
.
nbit
<
0
||
p
.
nbit
>=
ModbusRTU
::
BitsPerData
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRSProperty): BAD nbit="
<<
p
.
nbit
<<
". (0 >= nbit < "
<<
ModbusRTU
::
BitsPerData
<<
")."
<<
endl
;
return
false
;
}
}
if
(
p
.
nbit
>
0
&&
(
p
.
stype
==
UniversalIO
::
AnalogInput
||
p
.
stype
==
UniversalIO
::
AnalogOutput
)
)
{
dlog
[
Debug
::
WARN
]
<<
"(initRSProperty): (ignore) uncorrect param`s nbit>1 ("
<<
p
.
nbit
<<
")"
<<
" but iotype="
<<
p
.
stype
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
}
string
sbyte
(
it
.
getProp
(
prop_prefix
+
"nbyte"
));
if
(
!
sbyte
.
empty
()
)
{
p
.
nbyte
=
UniSetTypes
::
uni_atoi
(
sbyte
.
c_str
());
if
(
p
.
nbyte
<
0
||
p
.
nbyte
>
VTypes
::
Byte
::
bsize
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRSProperty): BAD nbyte="
<<
p
.
nbyte
<<
". (0 >= nbyte < "
<<
VTypes
::
Byte
::
bsize
<<
")."
<<
endl
;
return
false
;
}
}
string
vt
(
it
.
getProp
(
prop_prefix
+
"vtype"
));
if
(
vt
.
empty
()
)
{
p
.
rnum
=
VTypes
::
wsize
(
VTypes
::
vtUnknown
);
p
.
vType
=
VTypes
::
vtUnknown
;
}
else
{
VTypes
::
VType
v
(
VTypes
::
str2type
(
vt
));
if
(
v
==
VTypes
::
vtUnknown
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRSProperty): Unknown tcp_vtype='"
<<
vt
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
p
.
vType
=
v
;
p
.
rnum
=
VTypes
::
wsize
(
v
);
}
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
MBExchange
::
initRegInfo
(
RegInfo
*
r
,
UniXML_iterator
&
it
,
MBExchange
::
RTUDevice
*
dev
)
{
r
->
dev
=
dev
;
r
->
mbval
=
it
.
getIntProp
(
"default"
);
if
(
dev
->
dtype
==
MBExchange
::
dtRTU
)
{
// dlog[Debug::INFO] << myname << "(initRegInfo): init RTU.."
}
else
if
(
dev
->
dtype
==
MBExchange
::
dtMTR
)
{
// only for MTR
if
(
!
initMTRitem
(
it
,
r
)
)
return
false
;
}
else
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRegInfo): Unknown mbtype='"
<<
dev
->
dtype
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
if
(
mbregFromID
)
{
if
(
it
.
getProp
(
"id"
).
empty
()
)
r
->
mbreg
=
conf
->
getSensorID
(
it
.
getProp
(
"name"
));
else
r
->
mbreg
=
it
.
getIntProp
(
"id"
);
}
else
{
string
sr
=
it
.
getProp
(
prop_prefix
+
"mbreg"
);
if
(
sr
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): Unknown 'mbreg' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
r
->
mbreg
=
ModbusRTU
::
str2mbData
(
sr
);
}
r
->
mbfunc
=
ModbusRTU
::
fnUnknown
;
string
f
=
it
.
getProp
(
prop_prefix
+
"mbfunc"
);
if
(
!
f
.
empty
()
)
{
r
->
mbfunc
=
(
ModbusRTU
::
SlaveFunctionCode
)
UniSetTypes
::
uni_atoi
(
f
.
c_str
());
if
(
r
->
mbfunc
==
ModbusRTU
::
fnUnknown
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRegInfo): Unknown mbfunc ='"
<<
f
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
}
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
MBExchange
::
initRTUDevice
(
RTUDevice
*
d
,
UniXML_iterator
&
it
)
{
d
->
dtype
=
getDeviceType
(
it
.
getProp
(
prop_prefix
+
"mbtype"
));
if
(
d
->
dtype
==
dtUnknown
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRTUDevice): Unknown tcp_mbtype="
<<
it
.
getProp
(
prop_prefix
+
"mbtype"
)
<<
". Use: rtu "
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
string
addr
=
it
.
getProp
(
prop_prefix
+
"mbaddr"
);
if
(
addr
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initRTUDevice): Unknown mbaddr for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
d
->
mbaddr
=
ModbusRTU
::
str2mbAddr
(
addr
);
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
MBExchange
::
initItem
(
UniXML_iterator
&
it
)
{
RSProperty
p
;
if
(
!
initRSProperty
(
p
,
it
)
)
return
false
;
string
addr
=
it
.
getProp
(
prop_prefix
+
"mbaddr"
);
if
(
addr
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): Unknown mbaddr='"
<<
addr
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
ModbusRTU
::
ModbusAddr
mbaddr
=
ModbusRTU
::
str2mbAddr
(
addr
);
RTUDevice
*
dev
=
addDev
(
rmap
,
mbaddr
,
it
);
if
(
!
dev
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): "
<<
it
.
getProp
(
"name"
)
<<
" CAN`T ADD for polling!"
<<
endl
;
return
false
;
}
ModbusRTU
::
ModbusData
mbreg
;
if
(
mbregFromID
)
mbreg
=
p
.
si
.
id
;
// conf->getSensorID(it.getProp("name"));
else
{
string
reg
=
it
.
getProp
(
prop_prefix
+
"mbreg"
);
if
(
reg
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): unknown mbreg for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
mbreg
=
ModbusRTU
::
str2mbData
(
reg
);
}
int
fn
=
it
.
getIntProp
(
prop_prefix
+
"mbfunc"
);
// формула для вычисления ID
// требования:
// - ID > диапазона возможных регитров
// - разные функции должны давать разный ID
RegID
rID
=
genRegID
(
mbreg
,
fn
);
RegInfo
*
ri
=
addReg
(
dev
->
regmap
,
rID
,
mbreg
,
it
,
dev
);
if
(
dev
->
dtype
==
dtMTR
)
{
p
.
rnum
=
MTR
::
wsize
(
ri
->
mtrType
);
if
(
p
.
rnum
<=
0
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): unknown word size for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
}
if
(
!
ri
)
return
false
;
ri
->
dev
=
dev
;
// ПРОВЕРКА!
// если функция на запись, то надо проверить
// что один и тотже регистр не перезапишут несколько датчиков
// это возможно только, если они пишут биты!!
// ИТОГ:
// Если для функций записи список датчиков для регистра > 1
// значит в списке могут быть только битовые датчики
// и если идёт попытка внести в список не битовый датчик то ОШИБКА!
// И наоборот: если идёт попытка внести битовый датчик, а в списке
// уже сидит датчик занимающий целый регистр, то тоже ОШИБКА!
if
(
ModbusRTU
::
isWriteFunction
(
ri
->
mbfunc
)
)
{
if
(
p
.
nbit
<
0
&&
ri
->
slst
.
size
()
>
1
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): FAILED! Sharing SAVE (not bit saving) to "
<<
" tcp_mbreg="
<<
ModbusRTU
::
dat2str
(
ri
->
mbreg
)
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
abort
();
// ABORT PROGRAM!!!!
return
false
;
}
if
(
p
.
nbit
>=
0
&&
ri
->
slst
.
size
()
==
1
)
{
PList
::
iterator
it2
=
ri
->
slst
.
begin
();
if
(
it2
->
nbit
<
0
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): FAILED! Sharing SAVE (mbreg="
<<
ModbusRTU
::
dat2str
(
ri
->
mbreg
)
<<
" already used)!"
<<
" IGNORE --> "
<<
it
.
getProp
(
"name"
)
<<
endl
;
abort
();
// ABORT PROGRAM!!!!
return
false
;
}
}
// Раз это регистр для записи, то как минимум надо сперва
// инициализировать значением из SM
ri
->
sm_initOK
=
it
.
getIntProp
(
prop_prefix
+
"sm_initOK"
);
ri
->
mb_initOK
=
true
;
// может быть переопределён если будет указан tcp_preinit="1" (см. ниже)
}
else
{
// Если это регистр для чтения, то сразу можно работать
// инициализировать не надо
ri
->
mb_initOK
=
true
;
ri
->
sm_initOK
=
true
;
}
RSProperty
*
p1
=
addProp
(
ri
->
slst
,
p
);
if
(
!
p1
)
return
false
;
p1
->
reg
=
ri
;
if
(
p1
->
rnum
>
1
)
{
ri
->
q_count
=
p1
->
rnum
;
ri
->
q_num
=
1
;
for
(
int
i
=
1
;
i
<
p1
->
rnum
;
i
++
)
{
RegID
id1
=
genRegID
(
mbreg
+
i
,
ri
->
mbfunc
);
RegInfo
*
r
=
addReg
(
dev
->
regmap
,
id1
,
mbreg
+
i
,
it
,
dev
,
ri
);
r
->
q_num
=
i
+
1
;
r
->
q_count
=
1
;
r
->
mbfunc
=
ri
->
mbfunc
;
r
->
mb_initOK
=
true
;
r
->
sm_initOK
=
true
;
if
(
ModbusRTU
::
isWriteFunction
(
ri
->
mbfunc
)
)
{
// Если занимает несколько регистров, а указана функция записи "одного",
// то это ошибка..
if
(
ri
->
mbfunc
!=
ModbusRTU
::
fnWriteOutputRegisters
&&
ri
->
mbfunc
!=
ModbusRTU
::
fnForceMultipleCoils
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): Bad write function ='"
<<
ModbusRTU
::
fnWriteOutputSingleRegister
<<
"' for vtype='"
<<
p1
->
vType
<<
"'"
<<
" tcp_mbreg="
<<
ModbusRTU
::
dat2str
(
ri
->
mbreg
)
<<
" for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
abort
();
// ABORT PROGRAM!!!!
return
false
;
}
}
}
}
// Фомируем список инициализации
bool
need_init
=
it
.
getIntProp
(
prop_prefix
+
"preinit"
);
if
(
need_init
&&
ModbusRTU
::
isWriteFunction
(
ri
->
mbfunc
)
)
{
InitRegInfo
ii
;
ii
.
p
=
p
;
ii
.
dev
=
dev
;
ii
.
ri
=
ri
;
string
s_reg
(
it
.
getProp
(
prop_prefix
+
"init_mbreg"
));
if
(
!
s_reg
.
empty
()
)
ii
.
mbreg
=
ModbusRTU
::
str2mbData
(
s_reg
);
else
ii
.
mbreg
=
ri
->
mbreg
;
string
s_mbfunc
(
it
.
getProp
(
prop_prefix
+
"init_mbfunc"
));
if
(
!
s_mbfunc
.
empty
()
)
{
ii
.
mbfunc
=
(
ModbusRTU
::
SlaveFunctionCode
)
UniSetTypes
::
uni_atoi
(
s_mbfunc
);
if
(
ii
.
mbfunc
==
ModbusRTU
::
fnUnknown
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initItem): Unknown tcp_init_mbfunc ='"
<<
s_mbfunc
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
}
else
{
switch
(
ri
->
mbfunc
)
{
case
ModbusRTU
:
:
fnWriteOutputSingleRegister
:
ii
.
mbfunc
=
ModbusRTU
::
fnReadOutputRegisters
;
break
;
case
ModbusRTU
:
:
fnForceSingleCoil
:
ii
.
mbfunc
=
ModbusRTU
::
fnReadCoilStatus
;
break
;
case
ModbusRTU
:
:
fnWriteOutputRegisters
:
ii
.
mbfunc
=
ModbusRTU
::
fnReadOutputRegisters
;
break
;
case
ModbusRTU
:
:
fnForceMultipleCoils
:
ii
.
mbfunc
=
ModbusRTU
::
fnReadCoilStatus
;
break
;
default
:
ii
.
mbfunc
=
ModbusRTU
::
fnReadOutputRegisters
;
break
;
}
}
initRegList
.
push_back
(
ii
);
ri
->
mb_initOK
=
false
;
ri
->
sm_initOK
=
false
;
}
return
true
;
}
// ------------------------------------------------------------------------------------------
bool
MBExchange
::
initMTRitem
(
UniXML_iterator
&
it
,
RegInfo
*
p
)
{
p
->
mtrType
=
MTR
::
str2type
(
it
.
getProp
(
"mtrtype"
));
if
(
p
->
mtrType
==
MTR
::
mtUnknown
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(readMTRItem): Unknown mtrtype '"
<<
it
.
getProp
(
"mtrtype"
)
<<
"' for "
<<
it
.
getProp
(
"name"
)
<<
endl
;
return
false
;
}
return
true
;
}
// ------------------------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
MBExchange
::
DeviceType
&
dt
)
{
switch
(
dt
)
{
case
MBExchange
:
:
dtRTU
:
os
<<
"RTU"
;
break
;
case
MBExchange
:
:
dtMTR
:
os
<<
"MTR"
;
break
;
case
MBExchange
:
:
dtRTU188
:
os
<<
"RTU188"
;
break
;
default
:
os
<<
"Unknown device type ("
<<
(
int
)
dt
<<
")"
;
break
;
}
return
os
;
}
// -----------------------------------------------------------------------------
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
MBExchange
::
RSProperty
&
p
)
{
os
<<
" ("
<<
ModbusRTU
::
dat2str
(
p
.
reg
->
mbreg
)
<<
")"
<<
" sid="
<<
p
.
si
.
id
<<
" stype="
<<
p
.
stype
<<
" nbit="
<<
p
.
nbit
<<
" nbyte="
<<
p
.
nbyte
<<
" rnum="
<<
p
.
rnum
<<
" safety="
<<
p
.
safety
<<
" invert="
<<
p
.
invert
;
if
(
p
.
stype
==
UniversalIO
::
AnalogInput
||
p
.
stype
==
UniversalIO
::
AnalogOutput
)
{
os
<<
p
.
cal
<<
" cdiagram="
<<
(
p
.
cdiagram
?
"yes"
:
"no"
);
}
return
os
;
}
// -----------------------------------------------------------------------------
void
MBExchange
::
initDeviceList
()
{
xmlNode
*
respNode
=
conf
->
findNode
(
cnode
,
"DeviceList"
);
if
(
respNode
)
{
UniXML_iterator
it1
(
respNode
);
if
(
it1
.
goChildren
()
)
{
for
(;
it1
.
getCurrent
();
it1
.
goNext
()
)
{
ModbusRTU
::
ModbusAddr
a
=
ModbusRTU
::
str2mbAddr
(
it1
.
getProp
(
"addr"
));
initDeviceInfo
(
rmap
,
a
,
it1
);
}
}
else
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(init): <DeviceList> empty section..."
<<
endl
;
}
else
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(init): <DeviceList> not found..."
<<
endl
;
}
// -----------------------------------------------------------------------------
bool
MBExchange
::
initDeviceInfo
(
RTUDeviceMap
&
m
,
ModbusRTU
::
ModbusAddr
a
,
UniXML_iterator
&
it
)
{
RTUDeviceMap
::
iterator
d
=
m
.
find
(
a
);
if
(
d
==
m
.
end
()
)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(initDeviceInfo): not found device for addr="
<<
ModbusRTU
::
addr2str
(
a
)
<<
endl
;
return
false
;
}
d
->
second
->
ask_every_reg
=
it
.
getIntProp
(
"ask_every_reg"
);
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(initDeviceInfo): add addr="
<<
ModbusRTU
::
addr2str
(
a
)
<<
" ask_every_reg="
<<
d
->
second
->
ask_every_reg
<<
endl
;
string
s
(
it
.
getProp
(
"respondSensor"
));
if
(
!
s
.
empty
()
)
{
d
->
second
->
resp_id
=
conf
->
getSensorID
(
s
);
if
(
d
->
second
->
resp_id
==
DefaultObjectId
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(initDeviceInfo): not found ID for noRespondSensor="
<<
s
<<
endl
;
return
false
;
}
}
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(initDeviceInfo): add addr="
<<
ModbusRTU
::
addr2str
(
a
)
<<
endl
;
int
tout
=
it
.
getPIntProp
(
"timeout"
,
5000
);
d
->
second
->
resp_ptTimeout
.
setTiming
(
tout
);
d
->
second
->
resp_invert
=
it
.
getIntProp
(
"invert"
);
// d->second->no_clean_input = it.getIntProp("no_clean_input");
// dlog[Debug::INFO] << myname << "(initDeviceInfo): add " << (*d->second) << endl;
return
true
;
}
// -----------------------------------------------------------------------------
bool
MBExchange
::
activateObject
()
{
// блокирование обработки Starsp
// пока не пройдёт инициализация датчиков
// см. sysCommand()
{
setProcActive
(
false
);
UniSetTypes
::
uniset_mutex_lock
l
(
mutex_start
,
5000
);
UniSetObject_LT
::
activateObject
();
if
(
!
shm
->
isLocalwork
()
)
rtuQueryOptimization
(
rmap
);
initIterators
();
setProcActive
(
true
);
}
return
true
;
}
// ------------------------------------------------------------------------------------------
void
MBExchange
::
processingMessage
(
UniSetTypes
::
VoidMessage
*
msg
)
{
try
{
switch
(
msg
->
type
)
{
case
UniSetTypes
:
:
Message
::
SysCommand
:
{
UniSetTypes
::
SystemMessage
sm
(
msg
);
sysCommand
(
&
sm
);
}
break
;
case
Message
:
:
Timer
:
{
TimerMessage
tm
(
msg
);
timerInfo
(
&
tm
);
}
break
;
case
Message
:
:
SensorInfo
:
{
SensorMessage
sm
(
msg
);
sensorInfo
(
&
sm
);
}
break
;
default
:
break
;
}
}
catch
(
SystemError
&
ex
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(SystemError): "
<<
ex
<<
std
::
endl
;
// throw SystemError(ex);
}
catch
(
Exception
&
ex
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(processingMessage): "
<<
ex
<<
std
::
endl
;
}
catch
(...)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(processingMessage): catch ...
\n
"
;
}
}
// -----------------------------------------------------------------------------
void
MBExchange
::
sysCommand
(
UniSetTypes
::
SystemMessage
*
sm
)
{
switch
(
sm
->
command
)
{
case
SystemMessage
:
:
StartUp
:
{
if
(
rmap
.
empty
()
)
{
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(sysCommand): ************* ITEM MAP EMPTY! terminated... *************"
<<
endl
;
raise
(
SIGTERM
);
return
;
}
if
(
dlog
.
debugging
(
Debug
::
INFO
)
)
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(sysCommand): device map size= "
<<
rmap
.
size
()
<<
endl
;
if
(
!
shm
->
isLocalwork
()
)
initDeviceList
();
waitSMReady
();
// подождать пока пройдёт инициализация датчиков
// см. activateObject()
msleep
(
initPause
);
PassiveTimer
ptAct
(
activateTimeout
);
while
(
!
activated
&&
!
ptAct
.
checkTime
()
)
{
cout
<<
myname
<<
"(sysCommand): wait activate..."
<<
endl
;
msleep
(
300
);
if
(
activated
)
break
;
}
if
(
!
activated
)
dlog
[
Debug
::
CRIT
]
<<
myname
<<
"(sysCommand): ************* don`t activate?! ************"
<<
endl
;
{
UniSetTypes
::
uniset_mutex_lock
l
(
mutex_start
,
10000
);
askSensors
(
UniversalIO
::
UIONotify
);
initOutput
();
}
askTimer
(
tmExchange
,
polltime
);
break
;
}
case
SystemMessage
:
:
FoldUp
:
case
SystemMessage
:
:
Finish
:
askSensors
(
UniversalIO
::
UIODontNotify
);
break
;
case
SystemMessage
:
:
WatchDog
:
{
// ОПТИМИЗАЦИЯ (защита от двойного перезаказа при старте)
// Если идёт локальная работа
// (т.е. MBExchange запущен в одном процессе с SharedMemory2)
// то обрабатывать WatchDog не надо, т.к. мы и так ждём готовности SM
// при заказе датчиков, а если SM вылетит, то вместе с этим процессом(MBExchange)
if
(
shm
->
isLocalwork
()
)
break
;
askSensors
(
UniversalIO
::
UIONotify
);
initOutput
();
if
(
!
force
)
{
uniset_mutex_lock
l
(
pollMutex
,
2000
);
force
=
true
;
poll
();
force
=
false
;
}
}
break
;
case
SystemMessage
:
:
LogRotate
:
{
// переоткрываем логи
unideb
<<
myname
<<
"(sysCommand): logRotate"
<<
std
::
endl
;
string
fname
=
unideb
.
getLogFile
();
if
(
!
fname
.
empty
()
)
{
unideb
.
logFile
(
fname
);
unideb
<<
myname
<<
"(sysCommand): ***************** UNIDEB LOG ROTATE *****************"
<<
std
::
endl
;
}
dlog
<<
myname
<<
"(sysCommand): logRotate"
<<
std
::
endl
;
fname
=
dlog
.
getLogFile
();
if
(
!
fname
.
empty
()
)
{
dlog
.
logFile
(
fname
);
dlog
<<
myname
<<
"(sysCommand): ***************** dlog LOG ROTATE *****************"
<<
std
::
endl
;
}
}
break
;
default
:
break
;
}
}
// ------------------------------------------------------------------------------------------
void
MBExchange
::
initOutput
()
{
}
// ------------------------------------------------------------------------------------------
void
MBExchange
::
askSensors
(
UniversalIO
::
UIOCommand
cmd
)
{
if
(
!
shm
->
waitSMworking
(
test_id
,
activateTimeout
,
50
)
)
{
ostringstream
err
;
err
<<
myname
<<
"(askSensors): Не дождались готовности(work) SharedMemory к работе в течение "
<<
activateTimeout
<<
" мсек"
;
dlog
[
Debug
::
CRIT
]
<<
err
.
str
()
<<
endl
;
kill
(
SIGTERM
,
getpid
());
// прерываем (перезапускаем) процесс...
throw
SystemError
(
err
.
str
());
}
if
(
force_out
)
return
;
try
{
if
(
sidExchangeMode
!=
DefaultObjectId
)
shm
->
askSensor
(
sidExchangeMode
,
cmd
);
}
catch
(
UniSetTypes
::
Exception
&
ex
)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(askSensors): "
<<
ex
<<
std
::
endl
;
}
catch
(...)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(askSensors): 'sidExchangeMode' catch..."
<<
std
::
endl
;
}
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
if
(
!
isWriteFunction
(
it
->
second
->
mbfunc
)
)
continue
;
for
(
PList
::
iterator
i
=
it
->
second
->
slst
.
begin
();
i
!=
it
->
second
->
slst
.
end
();
++
i
)
{
try
{
shm
->
askSensor
(
i
->
si
.
id
,
cmd
);
}
catch
(
UniSetTypes
::
Exception
&
ex
)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(askSensors): "
<<
ex
<<
std
::
endl
;
}
catch
(...)
{
dlog
[
Debug
::
WARN
]
<<
myname
<<
"(askSensors): catch..."
<<
std
::
endl
;
}
}
}
}
}
// ------------------------------------------------------------------------------------------
void
MBExchange
::
sensorInfo
(
UniSetTypes
::
SensorMessage
*
sm
)
{
if
(
force_out
)
return
;
if
(
sm
->
id
==
sidExchangeMode
)
{
exchangeMode
=
sm
->
value
;
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(sensorInfo): exchange MODE="
<<
sm
->
value
<<
std
::
endl
;
return
;
}
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
if
(
!
isWriteFunction
(
it
->
second
->
mbfunc
)
)
continue
;
for
(
PList
::
iterator
i
=
it
->
second
->
slst
.
begin
();
i
!=
it
->
second
->
slst
.
end
();
++
i
)
{
if
(
sm
->
id
==
i
->
si
.
id
&&
sm
->
node
==
i
->
si
.
node
)
{
if
(
dlog
.
debugging
(
Debug
::
INFO
)
)
{
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(sensorInfo): si.id="
<<
sm
->
id
<<
" reg="
<<
ModbusRTU
::
dat2str
(
i
->
reg
->
mbreg
)
<<
" val="
<<
sm
->
value
<<
" mb_initOK="
<<
i
->
reg
->
mb_initOK
<<
endl
;
}
if
(
!
i
->
reg
->
mb_initOK
)
continue
;
i
->
value
=
sm
->
value
;
updateRSProperty
(
&
(
*
i
),
true
);
return
;
}
}
}
}
}
// ------------------------------------------------------------------------------------------
void
MBExchange
::
timerInfo
(
TimerMessage
*
tm
)
{
if
(
tm
->
id
==
tmExchange
)
{
if
(
no_extimer
)
askTimer
(
tm
->
id
,
0
);
else
step
();
}
}
// -----------------------------------------------------------------------------
void
MBExchange
::
poll
()
{
if
(
!
mb
)
{
{
uniset_mutex_lock
l
(
pollMutex
,
300
);
pollActivated
=
false
;
mb
=
initMB
(
false
);
if
(
!
mb
)
{
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it
=
rmap
.
begin
();
it
!=
rmap
.
end
();
++
it
)
it
->
second
->
resp_real
=
false
;
}
}
if
(
!
checkProcActive
()
)
return
;
updateSM
();
allInitOK
=
false
;
return
;
}
{
uniset_mutex_lock
l
(
pollMutex
);
pollActivated
=
true
;
ptTimeout
.
reset
();
}
if
(
!
allInitOK
)
firstInitRegisters
();
if
(
!
checkProcActive
()
)
return
;
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
if
(
dlog
.
debugging
(
Debug
::
INFO
)
)
dlog
[
Debug
::
INFO
]
<<
myname
<<
"(poll): ask addr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" regs="
<<
d
->
regmap
.
size
()
<<
endl
;
d
->
resp_real
=
false
;
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
if
(
!
checkProcActive
()
)
return
;
try
{
if
(
d
->
dtype
==
MBExchange
::
dtRTU
||
d
->
dtype
==
MBExchange
::
dtMTR
)
{
if
(
pollRTU
(
d
,
it
)
)
d
->
resp_real
=
true
;
}
}
catch
(
ModbusRTU
::
mbException
&
ex
)
{
// if( d->resp_real )
// {
if
(
dlog
.
debugging
(
Debug
::
LEVEL3
)
)
{
dlog
[
Debug
::
LEVEL3
]
<<
myname
<<
"(poll): FAILED ask addr="
<<
ModbusRTU
::
addr2str
(
d
->
mbaddr
)
<<
" reg="
<<
ModbusRTU
::
dat2str
(
it
->
second
->
mbreg
)
<<
" for sensors: "
;
print_plist
(
dlog
(
Debug
::
LEVEL3
),
it
->
second
->
slst
);
dlog
(
Debug
::
LEVEL3
)
<<
" err: "
<<
ex
<<
endl
;
}
// }
// d->resp_real = false;
if
(
ex
.
err
==
ModbusRTU
::
erTimeOut
&&
!
d
->
ask_every_reg
)
break
;
// если контроллер хоть что-то ответил, то вроде как связь есть..
if
(
ex
.
err
!=
ModbusRTU
::
erTimeOut
)
d
->
resp_real
=
true
;
}
if
(
it
==
d
->
regmap
.
end
()
)
break
;
if
(
!
checkProcActive
()
)
return
;
}
if
(
stat_time
>
0
)
poll_count
++
;
}
if
(
stat_time
>
0
&&
ptStatistic
.
checkTime
()
)
{
cout
<<
endl
<<
"(poll statistic): number of calls is "
<<
poll_count
<<
" (poll time: "
<<
stat_time
<<
" sec)"
<<
endl
<<
endl
;
ptStatistic
.
reset
();
poll_count
=
0
;
}
{
uniset_mutex_lock
l
(
pollMutex
);
pollActivated
=
false
;
}
if
(
!
checkProcActive
()
)
return
;
// update SharedMemory...
updateSM
();
// check thresholds
for
(
MBExchange
::
RTUDeviceMap
::
iterator
it1
=
rmap
.
begin
();
it1
!=
rmap
.
end
();
++
it1
)
{
RTUDevice
*
d
(
it1
->
second
);
for
(
MBExchange
::
RegMap
::
iterator
it
=
d
->
regmap
.
begin
();
it
!=
d
->
regmap
.
end
();
++
it
)
{
if
(
!
checkProcActive
()
)
return
;
RegInfo
*
r
(
it
->
second
);
for
(
PList
::
iterator
i
=
r
->
slst
.
begin
();
i
!=
r
->
slst
.
end
();
++
i
)
IOBase
::
processingThreshold
(
&
(
*
i
),
shm
,
force
);
}
}
// printMap(rmap);
}
// -----------------------------------------------------------------------------
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment