Commit 089e9ffb authored by Pavel Vainerman's avatar Pavel Vainerman

(MBExchange): начал выносить в базовый класс одинаковый

код для MBTCPMaster и RTUExchange
parent c12314b3
......@@ -12,20 +12,11 @@ using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
MBTCPMaster::MBTCPMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId,
SharedMemory* ic, const std::string prefix ):
UniSetObject_LT(objId),
MBExchange(objId,shmId,ic,prefix),
allInitOK(false),
mb(0),
shm(0),
initPause(0),
force(false),
force_out(false),
mbregFromID(false),
sidExchangeMode(DefaultObjectId),
activated(false),
noQueryOptimization(false),
force_disconnect(true),
prefix(prefix),
no_extimer(false),
force_disconnect(true),
poll_count(0),
pollThread(0)
{
......@@ -34,27 +25,8 @@ pollThread(0)
if( objId == DefaultObjectId )
throw UniSetTypes::SystemError("(MBTCPMaster): 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("(MBTCPMaster): 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);
// ---------- init MBTCP ----------
string pname("--" + prefix + "-gateway-iaddr");
iaddr = conf->getArgParam(pname,it.getProp("gateway_iaddr"));
......@@ -67,29 +39,14 @@ pollThread(0)
throw UniSetTypes::SystemError(myname+"(MBMaster): Unknown inet port...(Use: " + tmp +")" );
force_disconnect = conf->getArgInt("--" + prefix + "-persistent-connection",it.getProp("persistent_connection")) ? false : true;
dlog[Debug::INFO] << myname << "(init): persisten-connection=" << (!force_disconnect) << endl;
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"));
force_disconnect = conf->getArgInt("--" + prefix + "-persistent-connection",it.getProp("persistent_connection")) ? false : true;
dlog[Debug::INFO] << myname << "(init): persisten-connection=" << (!force_disconnect) << endl;
if( shm->isLocalwork() )
{
readConfiguration();
......@@ -99,60 +56,6 @@ pollThread(0)
else
ic->addReadItem( sigc::mem_fun(this,&MBTCPMaster::readItem) );
// ********** 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);
if( dlog.debugging(Debug::INFO) )
printMap(rmap);
poll_count = -1;
pollThread = new ThreadCreator<MBTCPMaster>(this, &MBTCPMaster::poll_thread);
}
// -----------------------------------------------------------------------------
......@@ -169,7 +72,6 @@ MBTCPMaster::~MBTCPMaster()
delete pollThread;
delete mb;
delete shm;
}
// -----------------------------------------------------------------------------
void MBTCPMaster::initMB( bool reopen )
......@@ -216,24 +118,6 @@ void MBTCPMaster::initMB( bool reopen )
}
// -----------------------------------------------------------------------------
void MBTCPMaster::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 MBTCPMaster::timerInfo( TimerMessage *tm )
{
if( tm->id == tmExchange )
......@@ -248,25 +132,8 @@ void MBTCPMaster::timerInfo( TimerMessage *tm )
void MBTCPMaster::step()
{
updateRespondSensors();
if( !activated )
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;
}
}
MBExchange::step();
}
// -----------------------------------------------------------------------------
void MBTCPMaster::updateRespondSensors()
{
......@@ -338,18 +205,6 @@ void MBTCPMaster::poll_thread()
}
}
// -----------------------------------------------------------------------------
bool MBTCPMaster::checkProcActive()
{
uniset_mutex_lock l(actMutex, 300);
return activated;
}
// -----------------------------------------------------------------------------
void MBTCPMaster::setProcActive( bool st )
{
uniset_mutex_lock l(actMutex, 400);
activated = st;
}
// -----------------------------------------------------------------------------
void MBTCPMaster::poll()
{
if( !mb )
......@@ -502,20 +357,8 @@ bool MBTCPMaster::pollRTU( RTUDevice* dev, RegMap::iterator& it )
}
}
if( exchangeMode == emWriteOnly && !ModbusRTU::isWriteFunction(p->mbfunc) )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << myname << "(pollRTU): skip.. mode='emWriteOnly'" << endl;
if( !checkPoll(ModbusRTU::isWriteFunction(p->mbfunc)) )
return true;
}
if( exchangeMode == emReadOnly && ModbusRTU::isWriteFunction(p->mbfunc) )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << myname << "(pollRTU): skip.. poll mode='emReadOnly'" << endl;
return false;
}
if( p->q_count == 0 )
{
......@@ -1317,41 +1160,6 @@ void MBTCPMaster::sigterm( int signo )
UniSetObject_LT::sigterm(signo);
}
// ------------------------------------------------------------------------------------------
void MBTCPMaster::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 MBTCPMaster::readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec )
{
if( UniSetTypes::check_filter(it,s_field,s_fvalue) )
initItem(it);
return true;
}
// ------------------------------------------------------------------------------------------
MBTCPMaster::RTUDevice* MBTCPMaster::addDev( RTUDeviceMap& mp, ModbusRTU::ModbusAddr a, UniXML_iterator& xmlit )
{
RTUDeviceMap::iterator it = mp.find(a);
......@@ -1599,20 +1407,6 @@ bool MBTCPMaster::initRegInfo( RegInfo* r, UniXML_iterator& it, MBTCPMaster::RT
return true;
}
// ------------------------------------------------------------------------------------------
MBTCPMaster::DeviceType MBTCPMaster::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;
}
// ------------------------------------------------------------------------------------------
bool MBTCPMaster::initRTUDevice( RTUDevice* d, UniXML_iterator& it )
{
d->dtype = getDeviceType(it.getProp("tcp_mbtype"));
......@@ -1881,9 +1675,7 @@ bool MBTCPMaster::initMTRitem( UniXML_iterator& it, RegInfo* p )
// ------------------------------------------------------------------------------------------
void MBTCPMaster::initIterators()
{
shm->initAIterator(aitHeartBeat);
shm->initAIterator(aitExchangeMode);
MBExchange::initIterators();
for( MBTCPMaster::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
......@@ -1903,32 +1695,19 @@ void MBTCPMaster::initIterators()
void MBTCPMaster::help_print( int argc, const char* const* argv )
{
cout << "Default: prefix='mbtcp'" << endl;
cout << "--prefix-name name - ObjectId (имя) процесса. По умолчанию: MBTCPMaster1" << 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;
MBExchange::help_print(argc,argv);
// ---------- init MBTCP ----------
// cout << "--prefix-sm-ready-timeout - время на ожидание старта SM" << endl;
cout << " Настройки протокола TCP: " << endl;
cout << "--prefix-gateway hostname,IP - IP опрашиваемого узла" << endl;
cout << "--prefix-gateway-port num - port на опрашиваемом узле" << endl;
cout << "--prefix-recv-timeout msec - Таймаут на приём одного сообщения." << endl;
cout << "--prefix-timeout msec - Таймаут для определения отсутсвия соединения" << endl;
cout << "--prefix-recv-timeout msec - Таймаут на приём одного сообщения" << endl;
cout << "--prefix-timeout msec - Таймаут для определения отсутсвия соединения" << endl;
cout << "--prefix-persistent-connection 0,1 - Не закрывать соединение на каждом цикле опроса" << endl;
}
// -----------------------------------------------------------------------------
MBTCPMaster* MBTCPMaster::init_mbmaster( int argc, const char* const* argv, UniSetTypes::ObjectId icID, SharedMemory* ic,
MBTCPMaster* MBTCPMaster::init_mbmaster( int argc, const char* const* argv,
UniSetTypes::ObjectId icID, SharedMemory* ic,
const std::string prefix )
{
string name = conf->getArgParam("--" + prefix + "-name","MBTCPMaster1");
......@@ -2069,18 +1848,18 @@ std::ostream& operator<<( std::ostream& os, MBTCPMaster::RTUDeviceMap& m )
// -----------------------------------------------------------------------------
std::ostream& operator<<( std::ostream& os, MBTCPMaster::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 << "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( MBTCPMaster::RegMap::iterator it=d.regmap.begin(); it!=d.regmap.end(); ++it )
os << " " << *(it->second) << endl;
os << " regs: " << endl;
for( MBTCPMaster::RegMap::iterator it=d.regmap.begin(); it!=d.regmap.end(); ++it )
os << " " << *(it->second) << endl;
return os;
}
......@@ -2187,30 +1966,9 @@ void MBTCPMaster::updateRSProperty( RSProperty* p, bool write_only )
if( !save && write_only )
return;
if( save && exchangeMode == emReadOnly )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << "updateP: sid=" << p->si.id
<< " skip... mode='emReadOnly' " << endl;
return;
}
if( !save && exchangeMode == emWriteOnly )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << "updateP: sid=" << p->si.id
<< " skip... mode='emWriteOnly' " << endl;
if( !checkUpdateSM(save) )
return;
}
if( save && exchangeMode == emSkipSaveToSM )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << "updateP: sid=" << p->si.id
<< " skip... mode='emSkipSaveToSM' " << endl;
return;
}
// если требуется инициализация и она ещё не произведена,
// то игнорируем
if( save && !r->mb_initOK )
......
......@@ -5,19 +5,8 @@
#include <string>
#include <map>
#include <vector>
#include "IONotifyController.h"
#include "UniSetObject_LT.h"
#include "MBExchange.h"
#include "modbus/ModbusTCPMaster.h"
#include "PassiveTimer.h"
#include "Trigger.h"
#include "Mutex.h"
#include "Calibration.h"
#include "SMInterface.h"
#include "SharedMemory.h"
#include "ThreadCreator.h"
#include "IOBase.h"
#include "VTypes.h"
#include "MTR.h"
// -----------------------------------------------------------------------------
/*!
\page page_ModbusTCP Реализация ModbusTCP master
......@@ -190,7 +179,7 @@
связи обновляется в основном потоке (чтобы не зависеть от TCP).
*/
class MBTCPMaster:
public UniSetObject_LT
public MBExchange
{
public:
MBTCPMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID, SharedMemory* ic=0,
......@@ -207,32 +196,12 @@ class MBTCPMaster:
void execute();
static const int NoSafetyState=-1;
/*! Режимы работы процесса обмена */
enum ExchangeMode
{
emNone, /*!< нормальная работа (по умолчанию) */
emWriteOnly, /*!< "только посылка данных" (работают только write-функции) */
emReadOnly, /*!< "только чтение" (работают только read-функции) */
emSkipSaveToSM /*!< не писать данные в SM (при этом работают и read и write функции */
};
enum Timer
{
tmExchange
};
enum DeviceType
{
dtUnknown, /*!< неизвестный */
dtRTU, /*!< RTU (default) */
dtMTR /*!< MTR (DEIF) */
};
static DeviceType getDeviceType( const std::string dtype );
friend std::ostream& operator<<( std::ostream& os, const DeviceType& dt );
// -------------------------------------------------------------------------------
// -----------------------------------------------------
struct RTUDevice;
struct RegInfo;
......@@ -346,7 +315,6 @@ class MBTCPMaster:
void printMap(RTUDeviceMap& d);
// ----------------------------------
static RegID genRegID( const ModbusRTU::ModbusData r, const int fn );
protected:
struct InitRegInfo
......@@ -380,13 +348,7 @@ class MBTCPMaster:
int port;
int recv_timeout;
xmlNode* cnode;
std::string s_field;
std::string s_fvalue;
SMInterface* shm;
void step();
virtual void step();
void poll_thread();
void poll();
bool pollRTU( RTUDevice* dev, RegMap::iterator& it );
......@@ -403,17 +365,12 @@ class MBTCPMaster:
void timerInfo( UniSetTypes::TimerMessage *tm );
void askSensors( UniversalIO::UIOCommand cmd );
void initOutput();
void waitSMReady();
void initMB( bool reopen=false );
virtual bool activateObject();
// действия при завершении работы
virtual void sigterm( int signo );
void initMB( bool reopen=false );
void initIterators();
bool initItem( UniXML_iterator& it );
bool readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec );
virtual void initIterators();
virtual bool initItem( UniXML_iterator& it );
void initDeviceList();
void initOffsetList();
......@@ -430,47 +387,16 @@ class MBTCPMaster:
void rtuQueryOptimization( RTUDeviceMap& m );
void readConfiguration();
bool checkProcActive();
void setProcActive( bool st );
private:
MBTCPMaster();
bool initPause;
UniSetTypes::uniset_mutex mutex_start;
bool force; /*!< флаг означающий, что надо сохранять в SM, даже если значение не менялось */
bool force_out; /*!< флаг означающий, принудительного чтения выходов */
bool mbregFromID;
int polltime; /*!< переодичность обновления данных, [мсек] */
timeout_t sleepPause_usec;
PassiveTimer ptHeartBeat;
UniSetTypes::ObjectId sidHeartBeat;
int maxHeartBeat;
IOController::AIOStateList::iterator aitHeartBeat;
UniSetTypes::ObjectId test_id;
UniSetTypes::ObjectId sidExchangeMode; /*!< иденидентификатор для датчика режима работы */
IOController::AIOStateList::iterator aitExchangeMode;
long exchangeMode; /*!< режим работы см. ExchangeMode */
UniSetTypes::uniset_mutex actMutex;
bool activated;
int activateTimeout;
bool noQueryOptimization;
bool force_disconnect;
std::string prefix;
bool no_extimer;
bool force_disconnect;
timeout_t stat_time; /*!< время сбора статистики обмена */
int poll_count;
PassiveTimer ptStatistic; /*!< таймер для сбора статистики обмена */
private:
MBTCPMaster();
// т.к. TCP может "зависнуть" на подключении к недоступному узлу
// делаем опрос в отдельном потоке
ThreadCreator<MBTCPMaster>* pollThread; /*!< поток опроса */
......
// -----------------------------------------------------------------------------
#include <cmath>
#include <sstream>
#include "Exceptions.h"
#include "Extensions.h"
#include "RTUExchange.h"
// -----------------------------------------------------------------------------
......@@ -11,40 +10,19 @@ using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
RTUExchange::RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId, SharedMemory* ic,
const std::string prefix_ ):
UniSetObject_LT(objId),
MBExchange(objId,shmId,ic,prefix_),
mb(0),
defSpeed(ComPort::ComSpeed0),
use485F(false),
transmitCtl(false),
shm(0),
initPause(0),
force(false),
force_out(false),
mbregFromID(false),
activated(false),
rs_pre_clean(false),
noQueryOptimization(false),
allNotRespond(false),
prefix(prefix_)
allNotRespond(false)
{
if( objId == DefaultObjectId )
throw UniSetTypes::SystemError("(RTUExchange): objId=-1?!! Use --" + prefix + "-name" );
// xmlNode* cnode = conf->getNode(myname);
cnode = conf->getNode(myname);
if( cnode == NULL )
throw UniSetTypes::SystemError("(RTUExchange): Not find conf-node 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;
// ---------- init RS ----------
// UniXML_iterator it(cnode);
devname = conf->getArgParam("--"+prefix+"-dev",it.getProp("device"));
......@@ -69,16 +47,6 @@ prefix(prefix_)
rs_pre_clean = conf->getArgInt("--"+prefix+"-pre-clean",it.getProp("pre_clean"));
noQueryOptimization = conf->getArgInt("--"+prefix+"-no-query-optimization",it.getProp("no_query_optimization"));
mbregFromID = conf->getArgInt("--mbs-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);
force = conf->getArgInt("--"+prefix+"-force",it.getProp("force"));
force_out = conf->getArgInt("--"+prefix+"-force-out",it.getProp("force_out"));
if( shm->isLocalwork() )
{
readConfiguration();
......@@ -88,48 +56,11 @@ prefix(prefix_)
else
ic->addReadItem( sigc::mem_fun(this,&RTUExchange::readItem) );
// ********** 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;
activateTimeout = conf->getArgPInt("--"+prefix+"-activate-timeout", 20000);
initMB(false);
printMap(rmap);
// abort();
if( dlog.debugging(Debug::INFO) )
printMap(rmap);
}
// -----------------------------------------------------------------------------
RTUExchange::~RTUExchange()
......@@ -150,7 +81,6 @@ RTUExchange::~RTUExchange()
}
delete mb;
delete shm;
}
// -----------------------------------------------------------------------------
void RTUExchange::initMB( bool reopen )
......@@ -198,24 +128,6 @@ void RTUExchange::initMB( bool reopen )
}
}
// -----------------------------------------------------------------------------
void RTUExchange::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): Не дождались готовности SharedMemory к работе в течение " << ready_timeout << " мсек";
dlog[Debug::CRIT] << err.str() << endl;
throw SystemError(err.str());
}
}
// -----------------------------------------------------------------------------
void RTUExchange::timerInfo( TimerMessage *tm )
{
if( tm->id == tmExchange )
......@@ -229,22 +141,7 @@ void RTUExchange::step()
poll();
}
if( !activated )
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;
}
}
MBExchange::step();
}
// -----------------------------------------------------------------------------
......@@ -388,7 +285,10 @@ bool RTUExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
<< " mb_init=" << p->mb_init
<< endl;
}
if( !checkPoll(ModbusRTU::isWriteFunction(p->mbfunc)) )
return true;
if( p->q_count == 0 )
{
if( dlog.debugging(Debug::INFO) )
......@@ -886,6 +786,8 @@ void RTUExchange::sensorInfo( UniSetTypes::SensorMessage* sm )
if( force_out )
return;
MBExchange::sensorInfo(sm);
for( RTUExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
......@@ -939,45 +841,9 @@ bool RTUExchange::activateObject()
void RTUExchange::sigterm( int signo )
{
cerr << myname << ": ********* SIGTERM(" << signo <<") ********" << endl;
activated = false;
UniSetObject_LT::sigterm(signo);
MBExchange::sigterm(signo);
}
// ------------------------------------------------------------------------------------------
void RTUExchange::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() )
{
std::cerr << 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 RTUExchange::readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec )
{
if( UniSetTypes::check_filter(it,s_field,s_fvalue) )
initItem(it);
return true;
}
// ------------------------------------------------------------------------------------------
RTUExchange::RTUDevice* RTUExchange::addDev( RTUDeviceMap& mp, ModbusRTU::ModbusAddr a, UniXML_iterator& xmlit )
{
RTUDeviceMap::iterator it = mp.find(a);
......@@ -1223,24 +1089,6 @@ bool RTUExchange::initRegInfo( RegInfo* r, UniXML_iterator& it, RTUExchange::RT
return true;
}
// ------------------------------------------------------------------------------------------
RTUExchange::DeviceType RTUExchange::getDeviceType( const std::string dtype )
{
if( dtype.empty() )
return dtUnknown;
if( dtype == "mtr" || dtype == "MTR" )
return dtMTR;
if( dtype == "rtu" || dtype == "RTU" )
return dtRTU;
if ( dtype == "rtu188" || dtype == "RTU188" )
return dtRTU188;
return dtUnknown;
}
// ------------------------------------------------------------------------------------------
bool RTUExchange::initRTUDevice( RTUDevice* d, UniXML_iterator& it )
{
d->dtype = getDeviceType(it.getProp("mbtype"));
......@@ -1442,7 +1290,7 @@ bool RTUExchange::initRTU188item( UniXML_iterator& it, RegInfo* p )
// -----------------------------------------------------------------------------
void RTUExchange::initIterators()
{
shm->initAIterator(aitHeartBeat);
MBExchange::initIterators();
for( RTUExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
......@@ -1463,14 +1311,8 @@ void RTUExchange::initIterators()
void RTUExchange::help_print( int argc, const char* const* argv )
{
cout << "Default: prefix='rs'" << endl;
cout << "--prefix-polltime msec - Пауза между опросаом карт. По умолчанию 200 мсек." << endl;
cout << "--prefix-heartbeat-id - Данный процесс связан с указанным аналоговым heartbeat-дачиком." << endl;
cout << "--prefix-heartbeat-max - Максимальное значение heartbeat-счётчика для данного процесса. По умолчанию 10." << endl;
cout << "--prefix-ready-timeout - Время ожидания готовности SM к работе, мсек. (-1 - ждать 'вечно')" << endl;
cout << "--prefix-force - Сохранять значения в SM, независимо от, того менялось ли значение" << endl;
cout << "--prefix-initPause - Задержка перед инициализацией (время на активизация процесса)" << endl;
cout << "--prefix-sm-ready-timeout - время на ожидание старта SM" << endl;
cout << " Настройки протокола RS: " << endl;
MBExchange::help_print(argc,argv);
// cout << " Настройки протокола RS: " << endl;
cout << "--prefix-dev devname - файл устройства" << endl;
cout << "--prefix-speed - Скорость обмена (9600,19920,38400,57600,115200)." << endl;
cout << "--prefix-my-addr - адрес текущего узла" << endl;
......@@ -1500,30 +1342,6 @@ RTUExchange* RTUExchange::init_rtuexchange( int argc, const char* const* argv, U
return new RTUExchange(ID,icID,ic,prefix);
}
// -----------------------------------------------------------------------------
std::ostream& operator<<( std::ostream& os, const RTUExchange::DeviceType& dt )
{
switch(dt)
{
case RTUExchange::dtRTU:
os << "RTU";
break;
case RTUExchange::dtRTU188:
os << "RTU188";
break;
case RTUExchange::dtMTR:
os << "MTR";
break;
default:
os << "Unknown device type (" << (int)dt << ")";
break;
}
return os;
}
// -----------------------------------------------------------------------------
std::ostream& operator<<( std::ostream& os, const RTUExchange::RSProperty& p )
{
os << " (" << ModbusRTU::dat2str(p.reg->mbreg) << ")"
......@@ -1750,6 +1568,9 @@ void RTUExchange::updateRSProperty( RSProperty* p, bool write_only )
if( !save && write_only )
return;
if( !checkUpdateSM(save) )
return;
try
{
if( p->vType == VTypes::vtUnknown )
......
......@@ -5,22 +5,12 @@
#include <string>
#include <map>
#include <vector>
#include "IONotifyController.h"
#include "UniSetObject_LT.h"
#include "MBExchange.h"
#include "modbus/ModbusRTUMaster.h"
#include "PassiveTimer.h"
#include "Trigger.h"
#include "Mutex.h"
#include "Calibration.h"
#include "SMInterface.h"
#include "SharedMemory.h"
#include "MTR.h"
#include "RTUStorage.h"
#include "IOBase.h"
#include "VTypes.h"
// -----------------------------------------------------------------------------
class RTUExchange:
public UniSetObject_LT
public MBExchange
{
public:
RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID,
......@@ -35,24 +25,12 @@ class RTUExchange:
/*! глобальная функция для вывода help-а */
static void help_print( int argc, const char* const* argv );
static const int NoSafetyState=-1;
enum Timer
{
tmExchange
};
enum DeviceType
{
dtUnknown, /*!< неизвестный */
dtRTU, /*!< RTU (default) */
dtRTU188, /*!< RTU188 (Fastwell) */
dtMTR /*!< MTR (DEIF) */
};
static DeviceType getDeviceType( const std::string dtype );
friend std::ostream& operator<<( std::ostream& os, const DeviceType& dt );
// -------------------------------------------------------------------------------
// --------------------------------------------------------
struct RTUDevice;
struct RegInfo;
......@@ -181,13 +159,7 @@ class RTUExchange:
bool use485F;
bool transmitCtl;
xmlNode* cnode;
std::string s_field;
std::string s_fvalue;
SMInterface* shm;
void step();
virtual void step();
void poll();
bool pollRTU( RTUDevice* dev, RegMap::iterator& it );
......@@ -198,12 +170,11 @@ class RTUExchange:
void updateRSProperty( RSProperty* p, bool write_only=false );
virtual void processingMessage( UniSetTypes::VoidMessage *msg );
void sysCommand( UniSetTypes::SystemMessage *msg );
void sensorInfo( UniSetTypes::SensorMessage*sm );
virtual void sysCommand( UniSetTypes::SystemMessage *msg );
virtual void sensorInfo( UniSetTypes::SensorMessage*sm );
void timerInfo( UniSetTypes::TimerMessage *tm );
void askSensors( UniversalIO::UIOCommand cmd );
void initOutput();
void waitSMReady();
virtual bool activateObject();
......@@ -211,13 +182,11 @@ class RTUExchange:
virtual void sigterm( int signo );
void initMB( bool reopen=false );
void initIterators();
virtual void initIterators();
bool initItem( UniXML_iterator& it );
bool readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec );
void initDeviceList();
void initOffsetList();
RTUDevice* addDev( RTUDeviceMap& dmap, ModbusRTU::ModbusAddr a, UniXML_iterator& it );
RegInfo* addReg( RegMap& rmap, ModbusRTU::ModbusData r, UniXML_iterator& it,
RTUDevice* dev, RegInfo* rcopy=0 );
......@@ -232,38 +201,14 @@ class RTUExchange:
void rtuQueryOptimization( RTUDeviceMap& m );
void readConfiguration();
private:
RTUExchange();
bool initPause;
UniSetTypes::uniset_mutex mutex_start;
bool force; /*!< флаг означающий, что надо сохранять в SM, даже если значение не менялось */
bool force_out; /*!< флаг означающий, принудительного чтения выходов */
bool mbregFromID;
int polltime; /*!< переодичность обновления данных, [мсек] */
timeout_t sleepPause_usec;
PassiveTimer ptHeartBeat;
UniSetTypes::ObjectId sidHeartBeat;
int maxHeartBeat;
IOController::AIOStateList::iterator aitHeartBeat;
UniSetTypes::ObjectId test_id;
UniSetTypes::uniset_mutex pollMutex;
bool activated;
int activateTimeout;
bool rs_pre_clean;
bool noQueryOptimization;
bool allNotRespond;
Trigger trAllNotRespond;
PassiveTimer ptAllNotRespond;
std::string prefix;
};
// -----------------------------------------------------------------------------
#endif // _RS_EXCHANGE_H_
......
#ifndef _MBExchange_H_
#define _MBExchange_H_
// -----------------------------------------------------------------------------
#include <ostream>
#include <string>
#include <map>
#include <vector>
#include "IONotifyController.h"
#include "UniSetObject_LT.h"
#include "PassiveTimer.h"
#include "Trigger.h"
#include "Mutex.h"
#include "Calibration.h"
#include "SMInterface.h"
#include "SharedMemory.h"
#include "ThreadCreator.h"
#include "IOBase.h"
#include "VTypes.h"
#include "MTR.h"
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
/*!
\par Базовый класс для реализация обмена по протоколу Modbus [RTU|TCP].
*/
class MBExchange:
public UniSetObject_LT
{
public:
MBExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID, SharedMemory* ic=0,
const std::string prefix="mb" );
virtual ~MBExchange();
/*! глобальная функция для вывода help-а */
static void help_print( int argc, const char* const* argv );
static const int NoSafetyState=-1;
/*! Режимы работы процесса обмена */
enum ExchangeMode
{
emNone, /*!< нормальная работа (по умолчанию) */
emWriteOnly, /*!< "только посылка данных" (работают только write-функции) */
emReadOnly, /*!< "только чтение" (работают только read-функции) */
emSkipSaveToSM /*!< не писать данные в SM (при этом работают и read и write функции */
};
friend std::ostream& operator<<( std::ostream& os, const ExchangeMode& em );
enum DeviceType
{
dtUnknown, /*!< неизвестный */
dtRTU, /*!< RTU (default) */
dtMTR, /*!< MTR (DEIF) */
dtRTU188 /*!< RTU188 (Fastwell) */
};
static DeviceType getDeviceType( const std::string dtype );
friend std::ostream& operator<<( std::ostream& os, const DeviceType& dt );
protected:
virtual void step();
virtual void sensorInfo( UniSetTypes::SensorMessage* sm );
virtual void sigterm( int signo );
virtual bool initItem( UniXML_iterator& it ){ return false; }
virtual void initIterators();
bool checkUpdateSM( bool wrFunc );
bool checkPoll( bool wrFunc );
bool checkProcActive();
void setProcActive( bool st );
void waitSMReady();
void readConfiguration();
bool readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec );
xmlNode* cnode;
std::string s_field;
std::string s_fvalue;
SMInterface* shm;
bool initPause;
UniSetTypes::uniset_mutex mutex_start;
bool force; /*!< флаг означающий, что надо сохранять в SM, даже если значение не менялось */
bool force_out; /*!< флаг означающий, принудительного чтения выходов */
bool mbregFromID;
int polltime; /*!< переодичность обновления данных, [мсек] */
timeout_t sleepPause_usec;
PassiveTimer ptHeartBeat;
UniSetTypes::ObjectId sidHeartBeat;
int maxHeartBeat;
IOController::AIOStateList::iterator aitHeartBeat;
UniSetTypes::ObjectId test_id;
UniSetTypes::ObjectId sidExchangeMode; /*!< иденидентификатор для датчика режима работы */
IOController::AIOStateList::iterator aitExchangeMode;
long exchangeMode; /*!< режим работы см. ExchangeMode */
UniSetTypes::uniset_mutex actMutex;
bool activated;
int activateTimeout;
bool noQueryOptimization;
std::string prefix;
timeout_t stat_time; /*!< время сбора статистики обмена */
int poll_count;
PassiveTimer ptStatistic; /*!< таймер для сбора статистики обмена */
private:
MBExchange();
};
// -----------------------------------------------------------------------------
#endif // _MBExchange_H_
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
#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),
shm(0),
initPause(0),
force(false),
force_out(false),
mbregFromID(false),
sidExchangeMode(DefaultObjectId),
activated(false),
noQueryOptimization(false),
prefix(prefix)
{
// 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 (имя) процесса. По умолчанию: MBTCPMaster1" << 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::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;
}
}
// ------------------------------------------------------------------------------------------
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);
}
// -----------------------------------------------------------------------------
std::ostream& operator<<( std::ostream& os, const MBExchange::DeviceType& dt )
{
switch(dt)
{
case MBExchange::dtRTU:
os << "RTU";
break;
case MBExchange::dtMTR:
os << "MTR";
break;
default:
os << "Unknown device type (" << (int)dt << ")";
break;
}
return os;
}
// -----------------------------------------------------------------------------
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;
}
// -----------------------------------------------------------------------------
......@@ -6,6 +6,6 @@ libUniSetExtensions_la_LDFLAGS = -version-info $(UEXT_VER)
libUniSetExtensions_la_CPPFLAGS = $(SIGC_CFLAGS) -I$(top_builddir)/extensions/include
libUniSetExtensions_la_LIBADD = $(SIGC_LIBS) $(top_builddir)/lib/libUniSet.la
libUniSetExtensions_la_SOURCES = Extensions.cc SMInterface.cc Calibration.cc SingleProcess.cc \
IOBase.cc DigitalFilter.cc PID.cc MTR.cc VTypes.cc
IOBase.cc DigitalFilter.cc PID.cc MTR.cc VTypes.cc MBExchange.cc
#UObject_SK.cc
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment