Commit 1fd3e894 authored by Pavel Vainerman's avatar Pavel Vainerman

Добавил поддержку пороговых датчиков для процессов обмена по Modbus(RTU|TCP)

parent 5589b01c
......@@ -8,7 +8,7 @@
Name: libuniset2
Version: 2.0
Release: alt0.5
Release: alt0.6
Summary: UniSet - library for building distributed industrial control systems
......@@ -333,6 +333,10 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
%exclude %_pkgconfigdir/libUniSet2.pc
%changelog
* Sun Feb 02 2014 Pavel Vainerman <pv@altlinux.ru> 2.0-alt0.6
- add thresholds processing for ModbusMaster (TCP and RTU)
- minor fixes
* Fri Jan 31 2014 Pavel Vainerman <pv@altlinux.ru> 2.0-alt0.5
- minor fixes
- test build
......
......@@ -228,6 +228,8 @@
<item id="58" iotype="AO" name="Lamp58_C" textname="Lamp 58" rrd="1" rrd1_ds="GAUGE:20:U:U"/>
<item id="62" iotype="AI" name="LogLevel_S" textname="LogLevel control"/>
<item id="63" iotype="AI" name="SVU_AskCount_AS" textname="svu asl count"/>
<item id="64" iotype="AI" name="AI64_AS" textname="AI64" mbaddr="0x01" mbfunc="0x03" mbreg="64" mbtype="rtu" rs="5"/>
<item id="65" iotype="DI" name="D65_S" textname="D65" threshold_aid="AI64_AS" lowlimit="3" hilimit="5" threshold_invert="1" rs="5" />
</sensors>
<thresholds name="thresholds">
<sensor iotype="AI" name="AI_AS">
......
......@@ -272,7 +272,10 @@ void IOControl::execute()
// init iterators
for( IOMap::iterator it=iomap.begin(); it!=iomap.end(); ++it )
{
shm->initIterator(it->ioit);
shm->initIterator(it->t_ait);
}
readconf_ok = true; // т.к. waitSM() уже был...
}
......
......@@ -261,7 +261,7 @@ int main(int argc, char* argv[])
if( comedi_dio_write(card, subdev, chan[k], val) < 0)
{
fprintf(stderr,"can't write 1 to channel %d. (%d) %s\n",k,errno,strerror(errno));
fprintf(stderr,"can't write 1 to channel %u. (%d) %s\n",k,errno,strerror(errno));
exret = EXIT_FAILURE;
}
}
......
......@@ -300,9 +300,18 @@ void MBExchange::initIterators()
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->initIterator(it2->ioit);
shm->initIterator(it2->t_ait);
}
}
}
for( MBExchange::ThresholdList::iterator t=thrlist.begin(); t!=thrlist.end(); ++t )
{
shm->initIterator(t->ioit);
shm->initIterator(t->t_ait);
}
}
// -----------------------------------------------------------------------------
bool MBExchange::checkUpdateSM( bool wrFunc, long mdev )
......@@ -1740,7 +1749,6 @@ MBExchange::RegInfo* MBExchange::addReg( RegMap& mp, RegID id, ModbusRTU::Modbus
<< " already added for " << (*it->second)
<< " Ignore register params for " << xmlit.getProp("name") << " ..." << endl;
it->second->rit = it;
return it->second;
}
......@@ -1790,6 +1798,17 @@ bool MBExchange::initRSProperty( RSProperty& p, UniXML_iterator& it )
if( !IOBase::initItem(&p,it,shm,&dlog,myname) )
return false;
// проверяем не пороговый ли это датчик (т.е. не связанный с обменом)
// тогда заносим его в отдельный список
if( p.t_ai != DefaultObjectId )
{
// испольуем конструктор копирования, чтобы сформировать IOBase
// через преобразование указателя к базовому классу
IOBase b( *(static_cast<IOBase*>(&p)) );
thrlist.push_back(b);
return true;
}
if( it.getIntProp(prop_prefix + "rawdata") )
{
p.cal.minRaw = 0;
......@@ -2724,18 +2743,12 @@ void MBExchange::poll()
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 )
for( MBExchange::ThresholdList::iterator t=thrlist.begin(); t!=thrlist.end(); ++t )
{
if( !checkProcActive() )
return;
RegInfo* r(it->second);
for( PList::iterator i=r->slst.begin(); i!=r->slst.end(); ++i )
IOBase::processingThreshold( &(*i),shm,force);
}
IOBase::processingThreshold(&(*t),shm,force);
}
if( trReopen.hi(allNotRespond) )
......
......@@ -323,6 +323,11 @@ class MBExchange:
PassiveTimer ptReopen; /*!< таймер для переоткрытия соединения */
Trigger trReopen;
// т.к. пороговые датчики не связаны напрямую с обменом, создаём для них отдельный список
// и отдельно его проверяем потом
typedef std::list<IOBase> ThresholdList;
ThresholdList thrlist;
private:
MBExchange();
......
......@@ -292,15 +292,12 @@ void RTUExchange::poll()
updateSM();
// check thresholds
for( MBExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
for( RTUExchange::RegMap::iterator it=d->regmap.begin(); it!=d->regmap.end(); ++it )
for( MBExchange::ThresholdList::iterator t=thrlist.begin(); t!=thrlist.end(); ++t )
{
RegInfo* r(it->second);
for( PList::iterator i=r->slst.begin(); i!=r->slst.end(); ++i )
IOBase::processingThreshold( &(*i),shm,force);
}
if( !checkProcActive() )
return;
IOBase::processingThreshold(&(*t),shm,force);
}
if( trReopen.hi(allNotRespond) )
......
#!/bin/sh
./uniset2-start.sh -f ./uniset2-mbtcpmaster \
./uniset-start.sh -f ./uniset2-mbtcpmaster \
--confile test.xml \
--mbtcp-name MBMaster1 \
--smemory-id SharedMemory \
......
......@@ -12,6 +12,7 @@ using namespace UniSetExtensions;
SMDBServer::SMDBServer( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId, SharedMemory* ic,
const string& prefix ):
DBServer_MySQL(objId),
aiignore(false),
prefix(prefix)
{
if( objId == DefaultObjectId )
......
......@@ -64,10 +64,10 @@ int main( int argc, const char** argv )
SystemMessage sm(SystemMessage::StartUp);
act.broadcast( sm.transport_msg() );
ulog.ebug::ANY) << "\n\n\n";
ulog.ebug::ANY] << "(main): -------------- SMDBServer START -------------------------\n\n";
dlog(Debug::ANY) << "\n\n\n";
dlog[Debug::ANY] << "(main): -------------- SMDBServer START -------------------------\n\n";
ulog << "\n\n\n";
ulog << "(main): -------------- SMDBServer START -------------------------\n\n";
dlog << "\n\n\n";
dlog << "(main): -------------- SMDBServer START -------------------------\n\n";
act.run(false);
return 0;
}
......
......@@ -92,6 +92,7 @@ static const int NoSafety = -1;
хранится идентификатор аналогового датчика
с которым он связан */
IONotifyController_i::ThresholdInfo ti;
IOController::IOStateList::iterator t_ait; // итератор для аналогового датчика
// Работа по фронтам сигнала
enum FrontType
......
......@@ -347,7 +347,7 @@ void IOBase::processingThreshold( IOBase* it, SMInterface* shm, bool force )
if( it->t_ai == DefaultObjectId )
return;
long val = shm->localGetValue(it->ioit,it->t_ai);
long val = shm->localGetValue(it->t_ait,it->t_ai);
bool set = it->value ? true : false;
// cout << "val=" << val << " set=" << set << endl;
......@@ -547,6 +547,7 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
b->ti.lowlimit = it.getIntProp("lowlimit");
b->ti.hilimit = it.getIntProp("hilimit");
b->ti.invert = it.getIntProp("threshold_invert");
shm->initIterator(b->t_ait);
}
}
......
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