Commit 0c003eb4 authored by Pavel Vainerman's avatar Pavel Vainerman

(2.0): Поменял механизм "зависимостей". Реализовал на освное сигналов(sigc),…

(2.0): Поменял механизм "зависимостей". Реализовал на освное сигналов(sigc), сменил формат. Теперь задаётся свойством depend='', depend_value='', depend_off_value=''
parent 16e0864b
......@@ -7,13 +7,11 @@ using namespace UniSetTypes;
using namespace std;
// --------------------------------------------------------------------------------
NullController::NullController( ObjectId id, const string askdump,
const std::string s_filterField,
const std::string s_filterValue,
const std::string c_filterField,
const std::string c_filterValue,
const std::string d_filterField,
const std::string d_filterValue,
NullController::NullController( ObjectId id, const string& askdump,
const std::string& s_filterField,
const std::string& s_filterValue,
const std::string& c_filterField,
const std::string& c_filterValue,
bool _dumpingToDB ):
IONotifyController(id),
dumpingToDB(_dumpingToDB)
......@@ -23,7 +21,6 @@ dumpingToDB(_dumpingToDB)
NCRestorer_XML* askd = new NCRestorer_XML(askdump);
askd->setItemFilter(s_filterField, s_filterValue);
askd->setConsumerFilter(c_filterField, c_filterValue);
askd->setDependsFilter(d_filterField, d_filterValue);
restorer = askd;
......
......@@ -10,13 +10,11 @@ class NullController:
public IONotifyController
{
public:
NullController( UniSetTypes::ObjectId id, const std::string restorfile,
const std::string s_filterField="",
const std::string s_filterValue="",
const std::string c_filterField="",
const std::string c_filterValue="",
const std::string d_filterField="",
const std::string d_filterValue="",
NullController( UniSetTypes::ObjectId id, const std::string& restorfile,
const std::string& s_filterField="",
const std::string& s_filterValue="",
const std::string& c_filterField="",
const std::string& c_filterValue="",
bool _dumpingToDB=false );
virtual ~NullController();
......
......@@ -16,8 +16,6 @@ static void short_usage()
<< " --s-filter-value value - значение для поля фильтрования списка датчиков \n"
<< " --c-filter-field name - поле для фильтрования списка заказчиков по каждому датчику\n"
<< " --c-filter-value value - значение для поля фильтрования списка заказчиков по каждому датчику\n"
<< " --d-filter-field name - поле для фильтрования списка зависимостей по каждому датчику\n"
<< " --d-filter-value value - значение для поля фильтрования списка зависимостей по каждому датчику\n"
<< " --dbDumping [0,1] - создавать ли dump-файл \n";
}
// --------------------------------------------------------------------------
......@@ -68,13 +66,11 @@ int main(int argc, char** argv)
string s_fvalue = conf->getArgParam("--s-filter-value");
string c_field = conf->getArgParam("--c-filter-field");
string c_fvalue = conf->getArgParam("--c-filter-value");
string d_field = conf->getArgParam("--d-filter-field");
string d_fvalue = conf->getArgParam("--d-filter-value");
// надо ли писать изменения в БД
bool dbDumping = conf->getArgInt("--dbDumping");
NullController nc(ID,askfile,s_field,s_fvalue,c_field,c_fvalue,d_field,d_fvalue,dbDumping);
NullController nc(ID,askfile,s_field,s_fvalue,c_field,c_fvalue,dbDumping);
ObjectsActivator act;
act.addObject(static_cast<class UniSetObject*>(&nc));
act.run(false);
......
......@@ -218,7 +218,7 @@ long <xsl:value-of select="$CLASSNAME"/>_SK::getValue( UniSetTypes::ObjectId _si
</xsl:if>
</xsl:for-each>
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] &lt;&lt; myname &lt;&lt; "(getValue): Обращение к неизвестному ДИСКРЕТНОМУ датчику sid="
unideb[Debug::CRIT] &lt;&lt; myname &lt;&lt; "(getValue): Обращение к неизвестному датчику sid="
&lt;&lt; _sid &lt;&lt; endl;
return 0;
......
......@@ -177,7 +177,7 @@ long <xsl:value-of select="$CLASSNAME"/>_SK::getValue( UniSetTypes::ObjectId _si
</xsl:for-each>
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] &lt;&lt; myname &lt;&lt; "(getValue): Обращение к неизвестному ДИСКРЕТНОМУ датчику sid="
unideb[Debug::CRIT] &lt;&lt; myname &lt;&lt; "(getValue): Обращение к неизвестному датчику sid="
&lt;&lt; _sid &lt;&lt; endl;
return 0;
......
......@@ -185,7 +185,7 @@ long <xsl:value-of select="$CLASSNAME"/>_SK::getValue( UniSetTypes::ObjectId _si
}
</xsl:for-each>
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] &lt;&lt; myname &lt;&lt; "(getValue): Обращение к неизвестному ДИСКРЕТНОМУ датчику sid="
unideb[Debug::CRIT] &lt;&lt; myname &lt;&lt; "(getValue): Обращение к неизвестному датчику sid="
&lt;&lt; _sid &lt;&lt; endl;
}
catch(Exception&amp; ex)
......
......@@ -174,7 +174,7 @@ long <xsl:value-of select="$CLASSNAME"/>_SK::getValue( UniSetTypes::ObjectId _si
return <xsl:call-template name="setprefix"/><xsl:value-of select="@name"/>;
</xsl:for-each>
unideb[Debug::CRIT] &lt;&lt; myname &lt;&lt; "(getValue): Обращение к неизвестному ДИСКРЕТНОМУ датчику sid="
unideb[Debug::CRIT] &lt;&lt; myname &lt;&lt; "(getValue): Обращение к неизвестному датчику sid="
&lt;&lt; _sid &lt;&lt; endl;
return 0;
}
......
......@@ -9,17 +9,28 @@
in - входные регистры (только для чтения)
out - выходные регистры (запись)
-->
<Skel>
<TestProc>
<settings>
<set name="class-name" val="Skel"/>
<set name="msg-count" val="20"/>
<set name="class-name" val="TestProc"/>
<set name="msg-count" val="30"/>
<set name="sleep-msec" val="150"/>
</settings>
<variables>
<item name="changeTime" type="int" default="2000" min="0" comment="change state time" const="1" public="1" />
<item name="checkTime" type="int" default="3000" min="0" comment="check Working time" const="1" public="1" />
<item name="checkDependTime" type="int" default="5000" min="0" comment="check depend time" const="1" public="1" />
</variables>
<smap>
<!-- name - название переменной в конф. файле -->
<item name="on_s" vartype="in" comment="Тестовый вход" smTestID="1"/>
<item name="lamp_c" vartype="out" comment="Лампочка (тестовый выход)"/>
<!-- проверка работы механизма зависимостей -->
<item name="depend_c" vartype="out" comment="Датчик от которого зависит состояние другого"/>
<item name="d_check_s" vartype="in" comment="состояние зависимого датчика"/>
<item name="set_d_check_s" vartype="out" comment="для выставления датчика"/>
</smap>
<msgmap>
<!-- name - название переменной в конф. файле -->
</msgmap>
</Skel>
</TestProc>
#include "Exceptions.h"
#include "TestGen.h"
#include "TestProc.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
// -----------------------------------------------------------------------------
TestGen::TestGen( UniSetTypes::ObjectId id, xmlNode* confnode ):
TestGen_SK( id, confnode )
TestProc::TestProc( UniSetTypes::ObjectId id, xmlNode* confnode ):
TestProc_SK( id, confnode ),
state(false)
{
}
// -----------------------------------------------------------------------------
TestGen::~TestGen()
TestProc::~TestProc()
{
}
// -----------------------------------------------------------------------------
TestGen::TestGen()
TestProc::TestProc():
state(false)
{
cerr << ": init failed!!!!!!!!!!!!!!!"<< endl;
throw Exception();
}
// -----------------------------------------------------------------------------
void TestGen::step()
void TestProc::step()
{
cout << "input2 state=" << in_input2_s << endl;
}
// -----------------------------------------------------------------------------
void TestGen::sensorInfo( SensorMessage *sm )
void TestProc::sysCommand( UniSetTypes::SystemMessage* sm )
{
if( sm->id == input1_s )
out_output1_c = in_input1_s; // sm->state
TestProc_SK::sysCommand(sm);
if( sm->command == SystemMessage::StartUp || sm->command == SystemMessage::WatchDog )
askTimer(tmCheckDepend,checkDependTime);
}
// -----------------------------------------------------------------------------
void TestGen::timerInfo( TimerMessage *tm )
void TestProc::sensorInfo( SensorMessage *sm )
{
dlog[Debug::INFO] << myname << "(sensorInfo): id=" << sm->id << " val=" << sm->value << endl;
if( sm->id == on_s )
{
if( sm->value )
{
dlog[Debug::LEVEL1] << myname << "(sensorInfo): START WORKING.." << endl;
askTimer(tmChange,changeTime);
}
else
{
askTimer(tmChange,0);
dlog[Debug::LEVEL1] << myname << "(sensorInfo): STOP WORKING.." << endl;
}
}
}
// -----------------------------------------------------------------------------
void TestGen::sigterm( int signo )
void TestProc::timerInfo( TimerMessage *tm )
{
TestGen_SK::sigterm(signo);
if( tm->id == tmChange )
{
state^=true;
out_lamp_c = ( state ? lmpBLINK : lmpOFF );
dlog[Debug::LEVEL1] << myname << "(timerInfo): state=" << state << " lmp=" << out_lamp_c << endl;
askTimer(tmCheckWorking,checkTime); // reset timer
}
else if( tm->id == tmCheckWorking )
dlog[Debug::LEVEL1] << myname << "(timerInfo): WORKING FAIL!" << endl;
else if( tm->id == tmCheckDepend )
{
dlog[Debug::LEVEL1] << myname << "(timerInfo): Check depend..." << endl;
long test_val = 100;
// set depend 0...
setValue(depend_c,0);
setValue(set_d_check_s,test_val);
dlog[Debug::LEVEL1] << myname << "(timerInfo): check depend OFF: " << ( getValue(d_check_s) == 0 ? "OK" : "FAIL" ) << endl;
// set depend 1
setValue(depend_c,1);
dlog[Debug::LEVEL1] << myname << "(timerInfo): check depend ON: " << ( getValue(d_check_s) == test_val ? "OK" : "FAIL" ) << endl;
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
#ifndef TestGen_H_
#define TestGen_H_
#ifndef TestProc_H_
#define TestProc_H_
// -----------------------------------------------------------------------------
#include "TestGen_SK.h"
#include "TestProc_SK.h"
// -----------------------------------------------------------------------------
class TestGen:
public TestGen_SK
class TestProc:
public TestProc_SK
{
public:
TestGen( UniSetTypes::ObjectId id, xmlNode* confnode = UniSetTypes::conf->getNode("TestGen") );
virtual ~TestGen();
TestProc( UniSetTypes::ObjectId id, xmlNode* confnode = UniSetTypes::conf->getNode("TestProc") );
virtual ~TestProc();
protected:
TestGen();
TestProc();
enum Timers
{
tmChange,
tmCheckWorking,
tmCheckDepend
};
virtual void step();
void sensorInfo( UniSetTypes::SensorMessage *sm );
void timerInfo( UniSetTypes::TimerMessage *tm );
virtual void sigterm( int signo );
virtual void sensorInfo( UniSetTypes::SensorMessage *sm );
virtual void timerInfo( UniSetTypes::TimerMessage *tm );
virtual void sysCommand( UniSetTypes::SystemMessage* sm );
private:
bool state;
};
// -----------------------------------------------------------------------------
#endif // TestGen_H_
#endif // TestProc_H_
// -----------------------------------------------------------------------------
......@@ -350,6 +350,7 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
- remove deprecated function setState,getState,askState
use simple function: setValue,getValue,askSensor
- possible use of the property 'iotype' in uniset-codegen
- refactoring <depends> mechanism
* Tue Dec 10 2013 Pavel Vainerman <pv@altlinux.ru> 1.7-alt3
- add RRDServer
......
......@@ -33,6 +33,14 @@
</UniSet>
<dlog name="dlog"/>
<settings>
<TestProc name="TestProc"
on_s="Input1_S"
lamp_c="Lamp58_C"
depend_c="Input4_S"
d_check_s="Input6_S"
set_d_check_s="Input6_S"
/>
<IOControl name="IOControl"/>
<testnode id="1000" id2="-100" name="testnode"/>
<SharedMemory name="SharedMemory" shmID="SharedMemory">
......@@ -160,11 +168,7 @@
<item id="3" iotype="DI" mbtcp="1" mbtcp_mbaddr="0x02" mbtcp_mbfunc="0x03" mbtcp_mbreg="0x02" mbtcp_mbtype="rtu" name="Input3_S" priority="Medium" textname="Команда 3"/>
<item id="4" iotype="DI" mbaddr="0x02" mbfunc="0x04" mbreg="0x02" mbtype="rtu" name="Input4_S" priority="Medium" rs="2" textname="Команда 4"/>
<item id="5" iotype="DI" name="Input5_S" priority="Medium" textname="Команда 5" udp="2"/>
<item id="6" iotype="DI" name="Input6_S" priority="Medium" textname="Команда 6" udp="2">
<depends>
<depend name="Input4_S"/>
</depends>
</item>
<item id="6" iotype="DI" name="Input6_S" priority="Medium" textname="Команда 6" udp="2" depend="Input4_S"/>
<item id="7" iotype="DO" name="DO_C" priority="Medium" textname="Digital output"/>
<item id="8" iotype="DO" name="DO1_C" priority="Medium" textname="Digital output"/>
<item default="1000" id="9" iotype="AO" name="AO_AS" precision="2" priority="Medium" rs="2" rs_channel="1" rs_jack="j1" rs_mbaddr="0x01" rs_mbfunc="0x06" rs_mbreg="0x02" rs_mbtype="rtu188" textname="Analog output"/>
......@@ -207,6 +211,7 @@
<item id="55" iotype="AI" name="AI55_S" textname="AI sensor 55" rrd="1" rrd1_ds="GAUGE:20:U:U"/>
<item id="56" iotype="AI" name="AI56_S" textname="AI sensor 56" rrd="2" rrd2_ds="COUNTER:20:U:U"/>
<item id="57" iotype="AI" name="AI57_S" textname="AI sensor 57" rrd="2" rrd2_ds="DERIVE:20:U:U"/>
<item id="58" iotype="AO" name="Lamp58_C" textname="Lamp 58" rrd="1" rrd1_ds="GAUGE:20:U:U"/>
</sensors>
<thresholds name="thresholds">
<sensor iotype="AI" name="AI_AS">
......@@ -244,6 +249,7 @@
<item id="6009" name="MBMaster2"/>
<item id="6010" name="MBMultiMaster1"/>
<item id="6011" name="RRDServer1"/>
<item id="6012" name="TestProc"/>
</objects>
</ObjectsMap>
<messages idfromfile="1" name="messages">
......
......@@ -18,8 +18,6 @@ void SharedMemory::help_print( int argc, const char* const* argv )
cout << "--s-filter-value - Значение фильтра для загрузки списка датчиков." << endl;
cout << "--c-filter-field - Фильтр для загрузки списка заказчиков." << endl;
cout << "--c-filter-value - Значение фильтр для загрузки списка заказчиков." << endl;
cout << "--d-filter-field - Фильтр для загрузки списка зависимостей." << endl;
cout << "--d-filter-value - Значение фильтр для загрузки списка зависимостей." << endl;
cout << "--wdt-device - Использовать в качестве WDT указанный файл." << endl;
cout << "--heartbeat-node - Загружать heartbeat датчики для указанного узла." << endl;
cout << "--heartbeat-check-time - период проверки 'счётчиков'. По умолчанию 1000 мсек" << endl;
......@@ -66,8 +64,6 @@ SharedMemory::SharedMemory( ObjectId id, string datafile, std::string confname )
string s_fvalue = conf->getArgParam("--s-filter-value");
string c_field = conf->getArgParam("--c-filter-field");
string c_fvalue = conf->getArgParam("--c-filter-value");
string d_field = conf->getArgParam("--d-filter-field");
string d_fvalue = conf->getArgParam("--d-filter-value");
string t_field = conf->getArgParam("--t-filter-field");
string t_fvalue = conf->getArgParam("--t-filter-value");
......@@ -81,11 +77,9 @@ SharedMemory::SharedMemory( ObjectId id, string datafile, std::string confname )
rxml->setItemFilter(s_field, s_fvalue);
rxml->setConsumerFilter(c_field, c_fvalue);
rxml->setDependsFilter(d_field, d_fvalue);
rxml->setThresholdsFilter(t_field, t_fvalue);
restorer = rxml;
rxml->setReadItem( sigc::mem_fun(this,&SharedMemory::readItem) );
string wdt_dev = conf->getArgParam("--wdt-device");
......
......@@ -39,7 +39,6 @@ static const int NoSafety = -1;
d_id(UniSetTypes::DefaultObjectId),
d_value(0),
d_off_value(0),
d_iotype(UniversalIO::UnknownIOType),
t_ai(UniSetTypes::DefaultObjectId)
{}
......@@ -89,10 +88,9 @@ static const int NoSafety = -1;
// Зависимость (d - depend)
UniSetTypes::ObjectId d_id; /*!< идентификатор датчика, от которого зависит данный */
IOController::IOStateList::iterator d_ioit; /*! итератор на датчик от которого зависит данный */
IOController::IOStateList::iterator d_it; /*! итератор на датчик от которого зависит данный */
long d_value; /*!< разрешающее работу значение датчика от которого зависит данный */
long d_off_value; /*!< блокирующее значение */
UniversalIO::IOType d_iotype;
// Порог
UniSetTypes::ObjectId t_ai; /*!< если данный датчик дискретный,
......
......@@ -97,7 +97,7 @@ bool IOBase::check_depend( SMInterface* shm )
if( d_id == DefaultObjectId )
return true;
if( shm->localGetValue(d_ioit,d_id) != d_value )
if( shm->localGetValue(d_it,d_id) != d_value )
return false;
return true;
......@@ -452,7 +452,7 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
b->f_filter_iir = false;
shm->initIterator(b->ioit);
shm->initIterator(b->d_ioit);
shm->initIterator(b->d_it);
string d_txt(it.getProp("depend"));
if( !d_txt.empty() )
......@@ -471,7 +471,6 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
// по умолчанию срабатывание на "1"
b->d_value = it.getProp("depend_value").empty() ? 1 : it.getIntProp("depend_value");
b->d_off_value = it.getIntProp("depend_off_value");
b->d_iotype = conf->getIOType(b->d_id);
}
if( b->stype == UniversalIO::AI || b->stype == UniversalIO::AO )
......
#!/bin/sh
START=uniset-start.sh
${START} -f ./smemory-test --confile test.xml --dlog-add-levels level1 --localNode LocalhostNode \
#--unideb-add-levels crit,warn,info
#system,level2,level8,level9
......@@ -98,26 +98,26 @@ class IOController:
public:
struct DependsInfo;
typedef std::list<DependsInfo> DependsList;
typedef sigc::signal<void,const IOController_i::SensorInfo&, long, IOController*> ChangeSignal;
/*! слот для подключения функции вызываемой при изменении состояния датчика
\param it - интератор из DependsList
\param bool - текущее состояние undefined (TRUE|FALSE)
*/
typedef sigc::slot<void,DependsList::iterator,bool> DependsSlot;
// signal по изменению определённого датчика
ChangeSignal signal_change_value( UniSetTypes::ObjectId id, UniSetTypes::ObjectId node );
ChangeSignal signal_change_value( const IOController_i::SensorInfo& si );
/*! \warning В данной реализации call-back функция только одна!
Потом можно будет перейти на список (типа AFilter и DFilter)
*/
void setDependsSlot( DependsSlot sl );
void setBlockDependsSlot( DependsSlot sl );
// предварительное объявление, чтобы в структуре объявить итератор..
struct USensorIOInfo;
typedef std::map<UniSetTypes::KeyType, USensorIOInfo> IOStateList;
struct USensorIOInfo:
public IOController_i::SensorIOInfo
{
USensorIOInfo():any(0),dlst_lock(false),block_value(0),db_ignore(false)
{ undefined = false; blocked=false; }
USensorIOInfo():any(0),db_ignore(false),d_value(0),d_off_value(0)
{
undefined = false;
d_si.id = UniSetTypes::DefaultObjectId;
d_si.node = UniSetTypes::DefaultObjectId;
}
virtual ~USensorIOInfo(){}
USensorIOInfo(IOController_i::SensorIOInfo& r);
......@@ -128,35 +128,29 @@ class IOController:
const USensorIOInfo& operator=(const IOController_i::SensorIOInfo& r);
USensorIOInfo& operator=(IOController_i::SensorIOInfo* r);
// Дополнительные (вспомогательные поля)
UniSetTypes::uniset_rwmutex val_lock; /*!< флаг блокирующий работу со значением */
IOStateList::iterator it;
void* any; /*!< расширение для возможности хранения своей информации */
DependsList dlst; /*!< список io зависящих от данного (для выставления поля undefined) */
bool dlst_lock; /*!< флаг блокирующий работу со списком */
long block_value;
bool db_ignore; /*!< не писать изменения в БД */
UniSetTypes::uniset_rwmutex val_lock; /*!< флаг блокирующий работу со значением */
};
// сигнал для реализации механизма зависимостией..
ChangeSignal changeSignal;
IOController_i::SensorInfo d_si; /*!< идентификатор датчика, от которого зависит данный */
long d_value; /*!< разрешающее работу значение датчика от которого зависит данный */
long d_off_value; /*!< блокирующее значение */
// Функции работы со списками датчиков (без изменения 'const')
typedef std::map<UniSetTypes::KeyType, USensorIOInfo> IOStateList;
void checkDepend( const IOController_i::SensorInfo& si , long newval, IOController* );
};
inline IOStateList::iterator ioBegin(){ return ioList.begin(); }
inline IOStateList::iterator ioEnd(){ return ioList.end(); }
inline IOStateList::iterator find(UniSetTypes::KeyType k){ return ioList.find(k); }
inline int ioCount(){ return ioList.size(); }
struct DependsInfo
{
DependsInfo( bool init=false );
DependsInfo( IOController_i::SensorInfo& si, IOStateList::iterator& it );
IOController_i::SensorInfo si;
IOStateList::iterator it;
bool block_invert; /*!< инвертирование логики для блокирования */
bool init;
};
// доступ к элементам через итератор
virtual void localSetValue( IOStateList::iterator& it, const IOController_i::SensorInfo& si,
CORBA::Long value, UniSetTypes::ObjectId sup_id );
......@@ -254,13 +248,8 @@ class IOController:
inline bool iofiltersEmpty(){ return iofilters.empty(); }
inline int iodiltersSize(){ return iofilters.size(); }
// ---------------------------
// note: функция вызывается рекурсивно!!!
void updateDepends( IOController::DependsList& lst, bool undefined, bool& lock );
void updateBlockDepends( IOController::DependsList& lst, bool blk_state, bool& lock );
private:
friend class AskDumper;
friend class NCRestorer;
IOStateList ioList; /*!< список с текущим состоянием аналоговых входов/выходов */
UniSetTypes::uniset_rwmutex ioMutex; /*!< замок для блокирования совместного доступа к ioList */
......@@ -269,9 +258,6 @@ class IOController:
IOFilterSlotList iofilters; /*!< список фильтров для аналоговых значений */
DependsSlot dslot; /*!< undefined depends slot */
DependsSlot bslot; /*!< block depends slot */
UniSetTypes::uniset_rwmutex loggingMutex; /*!< logging info mutex */
};
// --------------------------------------------------------------------------
......
......@@ -129,6 +129,9 @@ class IONotifyController:
const UniSetTypes::ConsumerInfo& ci, UniversalIO::UIOCommand cmd);
virtual void localSetValue( IOController::IOStateList::iterator& it,
const IOController_i::SensorInfo& si,
CORBA::Long value, UniSetTypes::ObjectId sup_id );
// -----------------------------------------------
typedef sigc::signal<void,UniSetTypes::SensorMessage*> ChangeSignal;
ChangeSignal signal_change_state(){ return changeSignal; }
......@@ -136,7 +139,6 @@ class IONotifyController:
// -------------------- !!!!!!!!! ---------------------------------
virtual IONotifyController_i::ThresholdsListSeq* getThresholdsList();
/*! Информация о заказчике */
struct ConsumerInfoExt:
public UniSetTypes::ConsumerInfo
......@@ -212,12 +214,9 @@ class IONotifyController:
ThresholdExtList list;
};
/*! массив пар датчик->список порогов */
/*! массив пар [датчик,список порогов] */
typedef std::map<UniSetTypes::KeyType,ThresholdsListInfo> AskThresholdMap;
virtual void localSetValue( IOController::IOStateList::iterator& it,
const IOController_i::SensorInfo& si,
CORBA::Long value, UniSetTypes::ObjectId sup_id );
protected:
IONotifyController();
virtual bool activateObject();
......@@ -228,7 +227,6 @@ class IONotifyController:
//! посылка информации об изменении состояния датчика
virtual void send(ConsumerList& lst, UniSetTypes::SensorMessage& sm);
//! проверка срабатывания пороговых датчиков
virtual void checkThreshold( IOStateList::iterator& li,
const IOController_i::SensorInfo& si, bool send=true );
......@@ -253,12 +251,9 @@ class IONotifyController:
/*! чтение dump-файла */
virtual void readDump();
/*! построение списка зависимостей по каждому io */
virtual void buildDependsList();
NCRestorer* restorer;
void onChangeUndefined( DependsList::iterator it, bool undefined );
// void onChangeUndefined( DependsList::iterator it, bool undefined );
UniSetTypes::uniset_rwmutex sig_mutex;
ChangeSignal changeSignal;
......
......@@ -64,8 +64,7 @@ class NCRestorer
SInfo &operator=(IOController_i::SensorIOInfo& inf);
};
virtual void read(IONotifyController* ic, const std::string fn="" )=0;
virtual void buildDependsList( IONotifyController* ic, const std::string fn="" )=0;
virtual void read(IONotifyController* ic, const std::string& fn="" )=0;
virtual void dump(IONotifyController* ic, SInfo& inf, const IONotifyController::ConsumerList& lst)=0;
virtual void dumpThreshold(IONotifyController* ic, SInfo& inf, const IONotifyController::ThresholdExtList& lst)=0;
......@@ -95,6 +94,8 @@ class NCRestorer
{
return ic->myioBegin();
}
static void init_depends_signals( IONotifyController* ic );
};
// ------------------------------------------------------------------------------------------
/*!
......@@ -110,25 +111,20 @@ class NCRestorer_XML:
/*!
\param fname - файл. (формата uniset-project)
*/
NCRestorer_XML(const std::string fname);
NCRestorer_XML(const std::string& fname);
/*!
\param fname - файл. (формата uniset-project)
\param sensor_filterField - читать из списка только те узлы, у которых filterField="filterValue"
\param sensor_filterValue - значение для фильтрования списка
*/
NCRestorer_XML( const std::string fname, const std::string sensor_filterField, const std::string sensor_filterValue="" );
NCRestorer_XML( const std::string& fname, const std::string& sensor_filterField, const std::string& sensor_filterValue="" );
virtual ~NCRestorer_XML();
NCRestorer_XML();
/*! Установить фильтр на чтение списка 'зависимостей')
\note Функцию необходимо вызывать до вызова buildDependsList(...)
*/
void setDependsFilter( const std::string filterField, const std::string filterValue="" );
/*! Установить фильтр на чтение списка 'порогов' */
void setThresholdsFilter( const std::string filterField, const std::string filterValue="" );
void setThresholdsFilter( const std::string& filterField, const std::string& filterValue="" );
bool setFileName( const std::string& file, bool create );
inline std::string getFileName(){ return fname; }
......@@ -144,64 +140,43 @@ class NCRestorer_XML:
*/
void setReadThresholdItem( ReaderSlot sl );
/*! установить функцию для callback-вызова при чтении списка зависимостей.
bool xxxMyClass::myfunc(UniXML& xml,
UniXML_iterator& it, xmlNode* sec)
uxml - интерфейс для работы с xml-файлом
it - интератор(указатель) на текущий считываемый xml-узел (<sensor>)
sec - указатель на корневой узел секции (<depend>)
*/
void setReadDependItem( ReaderSlot sl );
typedef sigc::slot<bool,UniXML&,UniXML_iterator&,xmlNode*,SInfo&> NCReaderSlot;
void setNCReadItem( NCReaderSlot sl );
virtual void read(IONotifyController* ic, const std::string filename="" );
virtual void read(IONotifyController* ic, const std::string& filename="" );
virtual void read(IONotifyController* ic, UniXML& xml );
virtual void dump(IONotifyController* ic, SInfo& inf, const IONotifyController::ConsumerList& lst);
virtual void dumpThreshold(IONotifyController* ic, SInfo& inf, const IONotifyController::ThresholdExtList& lst);
virtual void buildDependsList( IONotifyController* ic, const std::string fn="" );
virtual void buildDependsList( IONotifyController* ic, UniXML& xml );
protected:
bool check_thresholds_item( UniXML_iterator& it );
bool check_depend_item( UniXML_iterator& it );
void read_consumers(UniXML& xml, xmlNode* node, NCRestorer_XML::SInfo& inf, IONotifyController* ic );
void read_list(UniXML& xml, xmlNode* node, IONotifyController* ic);
void read_thresholds(UniXML& xml, xmlNode* node, IONotifyController* ic);
void build_depends( UniXML& xml, xmlNode* node, IONotifyController* ic );
void init( std::string fname );
void init( const std::string& fname );
bool getBaseInfo( UniXML& xml, xmlNode* it, IOController_i::SensorInfo& si );
bool getSensorInfo(UniXML& xml, xmlNode* snode, SInfo& si );
bool getConsumerList(UniXML& xml,xmlNode* node, IONotifyController::ConsumerList& lst);
bool getThresholdInfo(UniXML& xml,xmlNode* tnode, IONotifyController::ThresholdInfoExt& ti);
bool getDependsInfo( UniXML& xml, xmlNode* node, IOController::DependsInfo& di );
static void set_dumptime( UniXML& xml, xmlNode* node );
static xmlNode* bind_node(UniXML& xml, xmlNode* root, const std::string& nodename, const std::string nm="");
static xmlNode* rebind_node(UniXML& xml, xmlNode* root, const std::string& nodename, const std::string nm="");
static xmlNode* bind_node(UniXML& xml, xmlNode* root, const std::string& nodename, const std::string& nm="");
static xmlNode* rebind_node(UniXML& xml, xmlNode* root, const std::string& nodename, const std::string& nm="");
std::string s_filterField;
std::string s_filterValue;
std::string c_filterField;
std::string c_filterValue;
std::string d_filterField;
std::string d_filterValue;
std::string t_filterField;
std::string t_filterValue;
std::string fname;
UniXML uxml;
ReaderSlot rtslot;
ReaderSlot depslot;
NCReaderSlot ncrslot;
private:
......
......@@ -147,11 +147,19 @@ void IOController::localSetUndefinedState( IOStateList::iterator& li,
throw IOController_i::NameNotFound(err.str().c_str());
}
bool changed = false;
{ // lock
uniset_rwmutex_wrlock lock(li->second.val_lock);
changed = (li->second.undefined != undefined);
li->second.undefined = undefined;
updateDepends( li->second.dlst, undefined, li->second.dlst_lock );
} // unlock
try
{
if( changed )
li->second.changeSignal.emit(li->second.si, li->second.value, this);
}
catch(...){}
}
// ------------------------------------------------------------------------------------------
void IOController::fastSetValue( const IOController_i::SensorInfo& si, CORBA::Long value, UniSetTypes::ObjectId sup_id )
......@@ -192,6 +200,8 @@ void IOController::localSetValue( IOController::IOStateList::iterator& li,
throw IOController_i::NameNotFound(err.str().c_str());
}
bool changed = false;
{ // lock
uniset_rwmutex_wrlock lock(li->second.val_lock);
......@@ -209,13 +219,16 @@ void IOController::localSetValue( IOController::IOStateList::iterator& li,
<< " node: " << conf->oind->getMapName(si.node)
<< " value="<< value << endl;
}
long prev = li->second.value;
if( !blocked )
li->second.real_value = li->second.value;
if( blocked )
{
li->second.real_value = value;
li->second.value = li->second.block_value;
li->second.value = li->second.d_off_value;
}
else
{
......@@ -223,6 +236,8 @@ void IOController::localSetValue( IOController::IOStateList::iterator& li,
li->second.real_value = value;
}
changed = ( prev != li->second.value );
// запоминаем время изменения
struct timeval tm;
struct timezone tz;
......@@ -233,6 +248,13 @@ void IOController::localSetValue( IOController::IOStateList::iterator& li,
li->second.tv_usec = tm.tv_usec;
}
} // unlock
try
{
if( changed )
li->second.changeSignal.emit(li->second.si, li->second.value, this);
}
catch(...){}
}
// ------------------------------------------------------------------------------------------
IOType IOController::getIOType( const IOController_i::SensorInfo& si )
......@@ -249,55 +271,6 @@ IOType IOController::getIOType( const IOController_i::SensorInfo& si )
throw IOController_i::NameNotFound(err.str().c_str());
}
// ---------------------------------------------------------------------------
#if 0
void IOController::localSetValue( IOController::IOStateList::iterator& li,
const IOController_i::SensorInfo& si, CORBA::Long value,
UniSetTypes::ObjectId sup_id )
{
if( li == ioList.end() )
li = ioList.find( key(si.id, si.node) );
if( li!=ioList.end() && li->second.type == UniversalIO::AO )
{
{ // lock
uniset_rwmutex_wrlock lock(li->second.val_lock);
if( li->second.blocked )
li->second.real_value = value;
else
{
li->second.value = value;
li->second.real_value = value;
}
// запоминаем время изменения
struct timeval tm;
struct timezone tz;
tm.tv_sec = 0;
tm.tv_usec = 0;
gettimeofday(&tm,&tz);
li->second.tv_sec = tm.tv_sec;
li->second.tv_usec = tm.tv_usec;
if( unideb.debugging(Debug::INFO) )
{
unideb[Debug::INFO] << myname << "(localSetValue): save value for ("
<< si.id << ":" << si.node << ")"
<< conf->oind->getNameById(si.id, si.node) << " = " << value
<< " blocked=" << li->second.blocked
<<" --> val=" << li->second.value << endl;
}
return;
} // unlock
}
// -------------
ostringstream err;
err << myname << "(localSetValue): Unknown sensor (" << si.id << ":" << si.node << ")" << conf->oind->getNameById(si.id);
unideb[Debug::INFO] << err.str() << endl;
throw IOController_i::NameNotFound(err.str().c_str());
}
#endif
// ---------------------------------------------------------------------------
void IOController::ioRegistration( const USensorIOInfo& ainf, bool force )
{
// проверка задан ли контроллеру идентификатор
......@@ -305,6 +278,7 @@ void IOController::ioRegistration( const USensorIOInfo& ainf, bool force )
{
ostringstream err;
err << "(IOCOntroller::ioRegistration): КОНТРОЛЛЕРУ НЕ ЗАДАН ObjectId. Регистрация невозможна.";
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << err.str() << endl;
throw ResolveNameError(err.str().c_str());
}
......@@ -485,7 +459,7 @@ IOController_i::SensorIOInfo IOController::getSensorIOInfo( const IOController_i
// -------------
ostringstream err;
err << myname << "(getAInfo): Unknown sensor (" << si.id << ":" << si.node << ")"
err << myname << "(getSensorIOInfo): Unknown sensor (" << si.id << ":" << si.node << ")"
<< conf->oind->getNameById(si.id,si.node);
if( unideb.debugging(Debug::INFO) )
......@@ -555,20 +529,17 @@ IOController_i::CalibrateInfo IOController::getCalibrateInfo(const IOController_
// --------------------------------------------------------------------------------------------------------------
IOController::USensorIOInfo::USensorIOInfo(IOController_i::SensorIOInfo& ai):
IOController_i::SensorIOInfo(ai),
any(0),
dlst_lock(false)
any(0)
{}
IOController::USensorIOInfo::USensorIOInfo(const IOController_i::SensorIOInfo& ai):
IOController_i::SensorIOInfo(ai),
any(0),
dlst_lock(false)
any(0)
{}
IOController::USensorIOInfo::USensorIOInfo(IOController_i::SensorIOInfo* ai):
IOController_i::SensorIOInfo(*ai),
any(0),
dlst_lock(false)
any(0)
{}
IOController::USensorIOInfo&
......@@ -642,79 +613,6 @@ IOController::IOStateList::iterator IOController::myiofind(UniSetTypes::KeyType
return ioList.find(k);
}
// -----------------------------------------------------------------------------
IOController::DependsInfo::DependsInfo( bool init ):
block_invert(false),
init(init)
{
}
// -----------------------------------------------------------------------------
IOController::DependsInfo::DependsInfo( IOController_i::SensorInfo& si, IOStateList::iterator& it ):
si(si),
it(it),
block_invert(false),
init(true)
{
}
// -----------------------------------------------------------------------------
void IOController::updateDepends( IOController::DependsList& lst, bool undefined, bool& lst_lock )
{
// защита от "зацикливания" рекурсивного вызова функции
if( lst_lock || lst.empty() )
return;
lst_lock = true;
for( DependsList::iterator it=lst.begin(); it!=lst.end(); ++it )
{
if( it->it != myioEnd() )
{
if( it->it->second.undefined != undefined )
{
it->it->second.undefined = undefined;
dslot(it,undefined);
updateDepends( it->it->second.dlst,undefined,it->it->second.dlst_lock );
}
}
}
lst_lock = false;
}
// -----------------------------------------------------------------------------
void IOController::updateBlockDepends( IOController::DependsList& lst, bool blk_state, bool& lst_lock )
{
// защита от "зацикливания" рекурсивного вызова функции
if( lst_lock || lst.empty() )
return;
lst_lock = true;
for( DependsList::iterator it=lst.begin(); it!=lst.end(); ++it )
{
bool set_blk = it->block_invert ? blk_state : !blk_state;
if( it->it != myioEnd() )
{
if( it->it->second.blocked != set_blk )
{
long val = set_blk ? it->it->second.value : it->it->second.real_value;
it->it->second.blocked = set_blk;
localSetValue( it->it, it->si, val, getId() );
bslot(it,set_blk);
}
}
}
lst_lock = false;
}
// -----------------------------------------------------------------------------
void IOController::setDependsSlot( DependsSlot sl )
{
dslot = sl;
}
// -----------------------------------------------------------------------------
void IOController::setBlockDependsSlot( DependsSlot sl )
{
bslot = sl;
}
// -----------------------------------------------------------------------------
IOController_i::SensorInfoSeq* IOController::getSensorSeq( const IDSeq& lst )
{
int size = lst.length();
......@@ -782,6 +680,7 @@ IOController_i::ShortIOInfo IOController::getChangedTime( const IOController_i::
ostringstream err;
err << myname << "(getChangedTime): вход(выход) с именем "
<< conf->oind->getNameById(si.id) << " не найден";
if( unideb.debugging(Debug::INFO) )
unideb[Debug::INFO] << err.str() << endl;
throw IOController_i::NameNotFound(err.str().c_str());
}
......@@ -809,3 +708,41 @@ IOController_i::ShortMapSeq* IOController::getSensors()
return res;
}
// -----------------------------------------------------------------------------
IOController::ChangeSignal IOController::signal_change_value( const IOController_i::SensorInfo& si )
{
return signal_change_value( si.id, si.node );
}
// -----------------------------------------------------------------------------
IOController::ChangeSignal IOController::signal_change_value( UniSetTypes::ObjectId id, UniSetTypes::ObjectId node )
{
IOStateList::iterator it = ioList.find( key(id,node) );
if( it==ioList.end() )
{
ostringstream err;
err << myname << "(signal_change_value): вход(выход) с именем "
<< conf->oind->getNameById(id) << " не найден";
if( unideb.debugging(Debug::INFO) )
unideb[Debug::INFO] << err.str() << endl;
throw IOController_i::NameNotFound(err.str().c_str());
}
uniset_rwmutex_rlock lock(it->second.val_lock);
return it->second.changeSignal;
}
// -----------------------------------------------------------------------------
void IOController::USensorIOInfo::checkDepend( const IOController_i::SensorInfo& dep_si , long newvalue, IOController* ic )
{
bool changed = false;
{
uniset_rwmutex_wrlock lock(val_lock);
bool prev = blocked;
blocked = ( newvalue == d_value ) ? false : true;
changed = ( prev != blocked );
}
if( changed )
ic->localSetValue( it, si, real_value, ic->getId() );
}
// -----------------------------------------------------------------------------
......@@ -56,7 +56,6 @@ IONotifyController::IONotifyController(const string name, const string section,
{
// добавляем фильтры
addIOFilter( sigc::mem_fun(this,&IONotifyController::myIOFilter) );
setDependsSlot( sigc::mem_fun(this,&IONotifyController::onChangeUndefined) );
}
IONotifyController::IONotifyController( ObjectId id, NCRestorer* d ):
......@@ -68,7 +67,6 @@ IONotifyController::IONotifyController( ObjectId id, NCRestorer* d ):
{
// добавляем фильтры
addIOFilter( sigc::mem_fun(this,&IONotifyController::myIOFilter) );
setDependsSlot( sigc::mem_fun(this,&IONotifyController::onChangeUndefined) );
}
IONotifyController::~IONotifyController()
......@@ -320,7 +318,7 @@ void IONotifyController::localSetValue( IOController::IOStateList::iterator& li,
if( li == myioEnd() ) // ???
{
ostringstream err;
err << myname << "(localSetValue): аналоговый вход(выход) с именем "
err << myname << "(localSetValue): вход(выход) с именем "
<< conf->oind->getNameById(si.id) << " не найден";
if( unideb.debugging(Debug::INFO) )
......@@ -328,7 +326,7 @@ void IONotifyController::localSetValue( IOController::IOStateList::iterator& li,
throw IOController_i::NameNotFound(err.str().c_str());
}
IOController::localSetValue(li,si, value,sup_id);
IOController::localSetValue(li, si, value, sup_id);
// сравниваем именно с li->second.value
// т.к. фактическое сохранённое значение может быть изменено
......@@ -355,7 +353,6 @@ void IONotifyController::localSetValue( IOController::IOStateList::iterator& li,
try
{
//uniset_mutex_rlock l(sig_mutex,500);
uniset_rwmutex_rlock l(sig_mutex);
changeSignal.emit(&sm);
}
......@@ -381,9 +378,9 @@ void IONotifyController::localSetValue( IOController::IOStateList::iterator& li,
checkThreshold(li,si,true);
}
catch(...){}
>>>>>>> (2.0): Поменял механизм "зависимостей". Реализовал на освное сигналов(sigc), сменил формат. Теперь задаётся свойством depend='', depend_value='', depend_off_value=''
}
// ------------------------------------------------------------------------------------------
/*!
\note В случае зависания в функции push, будут остановлены рассылки другим объектам.
Возможно нужно ввести своего агента на удалённой стороне, который будет заниматься
......@@ -410,17 +407,20 @@ void IONotifyController::send(ConsumerList& lst, UniSetTypes::SensorMessage& sm)
}
catch(Exception& ex)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(IONotifyController::send): " << ex
<< " for " << conf->oind->getNameById(li->id, li->node) << endl;
}
catch( CORBA::SystemException& ex )
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(IONotifyController::send): "
<< conf->oind->getNameById(li->id, li->node) << " (CORBA::SystemException): "
<< ex.NP_minorString() << endl;
}
catch(...)
{
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << myname << "(IONotifyController::send): "
<< conf->oind->getNameById(li->id, li->node)
<< " catch..." << endl;
......@@ -446,7 +446,6 @@ bool IONotifyController::activateObject()
{
IOController::activateObject();
readDump();
buildDependsList();
return true;
}
// --------------------------------------------------------------------------------------------------------------
......@@ -459,6 +458,7 @@ void IONotifyController::readDump()
}
catch(Exception& ex)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(IONotifyController::readDump): " << ex << endl;
}
}
......@@ -478,6 +478,7 @@ void IONotifyController::dumpOrdersList(const IOController_i::SensorInfo& si,
}
catch(Exception& ex)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(IONotifyController::dumpOrderList): " << ex << endl;
}
}
......@@ -497,6 +498,7 @@ void IONotifyController::dumpThresholdList(const IOController_i::SensorInfo& si,
}
catch(Exception& ex)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(IONotifyController::dumpThresholdList): " << ex << endl;
}
}
......@@ -544,10 +546,12 @@ void IONotifyController::askThreshold(const IOController_i::SensorInfo& si, cons
}
catch(Exception& ex)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << " не смогли сделать dump: " << ex << endl;
}
catch(...)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << " не смогли сделать dump" << endl;
}
}
......@@ -561,10 +565,12 @@ void IONotifyController::askThreshold(const IOController_i::SensorInfo& si, cons
}
catch(Exception& ex)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(askThreshold): dump: " << ex << endl;
}
catch(...)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(askThreshold): dump catch..." << endl;
}
}
......@@ -610,14 +616,20 @@ void IONotifyController::askThreshold(const IOController_i::SensorInfo& si, cons
}
catch(Exception& ex)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(askThreshod): " << ex << endl;
}
catch( CORBA::SystemException& ex )
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(askThreshod): CORBA::SystemException: "
<< ex.NP_minorString() << endl;
}
catch(...){}
catch(...)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(askThreshold): dump catch..." << endl;
}
}
break;
......@@ -633,10 +645,12 @@ void IONotifyController::askThreshold(const IOController_i::SensorInfo& si, cons
}
catch(Exception& ex)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(askThreshold): dump: " << ex << endl;
}
catch(...)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(askThreshold): dump catch..." << endl;
}
}
......@@ -774,6 +788,7 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li,
}
catch( UniSetTypes::Exception& ex )
{
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << myname << "(checkThreshold): "
<< ex << endl;
}
......@@ -937,6 +952,7 @@ IONotifyController_i::ThresholdsListSeq* IONotifyController::getThresholdsList()
}
catch(Exception& ex)
{
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << myname << "(getThresholdsList): для датчика "
<< conf->oind->getNameById(it->second.si.id, it->second.si.node)
<< " " << ex << endl;
......@@ -963,20 +979,7 @@ IONotifyController_i::ThresholdsListSeq* IONotifyController::getThresholdsList()
return res;
}
// -----------------------------------------------------------------------------
void IONotifyController::buildDependsList()
{
try
{
if( restorer != NULL )
restorer->buildDependsList(this);
}
catch(Exception& ex)
{
unideb[Debug::WARN] << myname
<< "(IONotifyController::buildDependsList): " << ex << endl;
}
}
// -----------------------------------------------------------------------------
#if 0
void IONotifyController::onChangeUndefined( DependsList::iterator it, bool undefined )
{
SensorMessage sm;
......@@ -1010,6 +1013,7 @@ void IONotifyController::onChangeUndefined( DependsList::iterator it, bool undef
send(it1->second, sm);
} // unlock
}
#endif
// -----------------------------------------------------------------------------
IDSeq* IONotifyController::askSensorsSeq( const UniSetTypes::IDSeq& lst,
const UniSetTypes::ConsumerInfo& ci,
......
......@@ -3,9 +3,10 @@
############################################################################
noinst_LTLIBRARIES = libProcesses.la
libProcesses_la_SOURCES = IOController_iSK.cc IOController.cc IONotifyController.cc IONotifyController_LT.cc
libProcesses_la_CXXFLAGS = $(SIGC_CFLAGS)
libProcesses_la_LIBADD = $(SIGC_LIBS)
libProcesses_la_SOURCES = IOController_iSK.cc IOController.cc IONotifyController.cc IONotifyController_LT.cc \
NCRestorer.cc NCRestorer_XML.cc
include $(top_builddir)/conf/setting.mk
......
......@@ -177,3 +177,24 @@ NCRestorer::SInfo& NCRestorer::SInfo::operator=(IOController_i::SensorIOInfo& in
return *this;
}
// ------------------------------------------------------------------------------------------
void NCRestorer::init_depends_signals( IONotifyController* ic )
{
for( IOController::IOStateList::iterator it=ic->ioList.begin(); it!=ic->ioList.end(); ++it )
{
// обновляем итераторы...
it->second.it = it;
if( it->second.d_si.id == DefaultObjectId )
continue;
if( unideb.debugging(Debug::INFO) )
unideb[Debug::INFO] << ic->getName() << "(NCRestorer::init_depends_signals): "
<< " init depend: '" << conf->oind->getMapName(it->second.si.id) << "'"
<< " dep_name='" << conf->oind->getMapName(it->second.d_si.id) << "'"
<< endl;
IOController::ChangeSignal s = ic->signal_change_value(it->second.d_si);
s.connect( sigc::mem_fun( &it->second, &IOController::USensorIOInfo::checkDepend) );
}
}
// -----------------------------------------------------------------------------
......@@ -32,13 +32,11 @@ using namespace std;
using namespace UniversalIO;
using namespace UniSetTypes;
// ------------------------------------------------------------------------------------------
NCRestorer_XML::NCRestorer_XML( const string fname ):
NCRestorer_XML::NCRestorer_XML( const string& fname ):
s_filterField(""),
s_filterValue(""),
c_filterField(""),
c_filterValue(""),
d_filterField(""),
d_filterValue(""),
t_filterField(""),
t_filterValue(""),
fname(fname)
......@@ -46,15 +44,13 @@ fname(fname)
init(fname);
}
NCRestorer_XML::NCRestorer_XML(const string fname,
const std::string f_field,
const std::string f_value):
NCRestorer_XML::NCRestorer_XML(const string& fname,
const std::string& f_field,
const std::string& f_value):
s_filterField(f_field),
s_filterValue(f_value),
c_filterField(""),
c_filterValue(""),
d_filterField(""),
d_filterValue(""),
t_filterField(""),
t_filterValue(""),
fname(fname)
......@@ -74,7 +70,7 @@ NCRestorer_XML::~NCRestorer_XML()
uxml.close();
}
// ------------------------------------------------------------------------------------------
void NCRestorer_XML::init( std::string fname )
void NCRestorer_XML::init( const std::string& fname )
{
/*!
\warning Файл открывается только при создании...
......@@ -157,7 +153,7 @@ void NCRestorer_XML::read_list( UniXML& xml, xmlNode* node, IONotifyController*
}
}
// ------------------------------------------------------------------------------------------
void NCRestorer_XML::read( IONotifyController* ic, const string fn )
void NCRestorer_XML::read( IONotifyController* ic, const string& fn )
{
UniXML* confxml = conf->getConfXML();
......@@ -197,7 +193,12 @@ void NCRestorer_XML::read( IONotifyController* ic, UniXML& xml )
node = xml.findNode(xml.getFirstNode(),"sensors");
if( node )
{
read_list(xml, node, ic);
// только после чтения всех датчиков и формирования списка IOList
// можно инициализировать списки зависимостей
init_depends_signals(ic);
}
xmlNode* tnode( xml.findNode(xml.getFirstNode(),"thresholds") );
if( tnode )
......@@ -210,7 +211,8 @@ bool NCRestorer_XML::getBaseInfo( UniXML& xml, xmlNode* it, IOController_i::Sens
string sname( xml.getProp(it,"name"));
if( sname.empty() )
{
unideb[Debug::WARN] << "(getSensorInfo): не указано имя датчика... пропускаем..." << endl;
if( unideb.debugging(Debug::WARN) )
unideb[Debug::WARN] << "(getBaseInfo): не указано имя датчика... пропускаем..." << endl;
return false;
}
......@@ -225,7 +227,8 @@ bool NCRestorer_XML::getBaseInfo( UniXML& xml, xmlNode* it, IOController_i::Sens
if( sid == UniSetTypes::DefaultObjectId )
{
unideb[Debug::CRIT] << "(getSensorInfo): НЕ НАЙДЕН ИДЕНТИФИКАТОР датчика --> " << sname << endl;
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << "(getBaseInfo): НЕ НАЙДЕН ИДЕНТИФИКАТОР датчика --> " << sname << endl;
return false;
}
......@@ -236,7 +239,8 @@ bool NCRestorer_XML::getBaseInfo( UniXML& xml, xmlNode* it, IOController_i::Sens
if( snode == UniSetTypes::DefaultObjectId )
{
unideb[Debug::CRIT] << "(getSensorInfo): НЕ НАЙДЕН ИДЕНТИФИКАТОР узла --> " << snodename << endl;
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << "(getBaseInfo): НЕ НАЙДЕН ИДЕНТИФИКАТОР узла --> " << snodename << endl;
return false;
}
......@@ -270,7 +274,6 @@ bool NCRestorer_XML::getSensorInfo( UniXML& xml, xmlNode* it, SInfo& inf )
}
}
inf.type = UniSetTypes::getIOType(xml.getProp(it,"iotype"));
if( inf.type == UniversalIO::UnknownIOType )
{
......@@ -304,6 +307,28 @@ bool NCRestorer_XML::getSensorInfo( UniXML& xml, xmlNode* it, SInfo& inf )
inf.value = inf.default_val;
inf.undefined = false;
inf.real_value = inf.value;
string d_txt( xml.getProp(it, "depend") );
if( !d_txt.empty() )
{
inf.d_si.id = conf->getSensorID(d_txt);
if( inf.d_si.id == UniSetTypes::DefaultObjectId )
{
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << "(NCRestorer_XML:getSensorInfo): sensor='"
<< xml.getProp(it,"name") << "' err: "
<< " Unknown SensorID for depend='" << d_txt
<< endl;
return false;
}
inf.d_si.node = conf->getLocalNode();
// по умолчанию срабатывание на "1"
inf.d_value = xml.getProp(it,"depend_value").empty() ? 1 : xml.getIntProp(it,"depend_value");
inf.d_off_value = xml.getPIntProp(it,"depend_off_value",0);
}
return true;
}
// ------------------------------------------------------------------------------------------
......@@ -473,184 +498,14 @@ void NCRestorer_XML::setReadThresholdItem( ReaderSlot sl )
rtslot = sl;
}
// ------------------------------------------------------------------------------------------
void NCRestorer_XML::setReadDependItem( ReaderSlot sl )
{
depslot = sl;
}
// ------------------------------------------------------------------------------------------
void NCRestorer_XML::setDependsFilter( const std::string field, const std::string val )
{
d_filterField = field;
d_filterValue = val;
}
// -----------------------------------------------------------------------------
void NCRestorer_XML::setThresholdsFilter( const std::string field, const std::string val )
{
t_filterField = field;
t_filterValue = val;
}
// -----------------------------------------------------------------------------
void NCRestorer_XML::setNCReadItem( NCReaderSlot sl )
{
ncrslot = sl;
}
// -----------------------------------------------------------------------------
void NCRestorer_XML::buildDependsList( IONotifyController* ic, const std::string fn )
{
UniXML* confxml = conf->getConfXML();
if( !fn.empty() )
{
// оптимизация (не загружаем второй раз xml-файл)
if( fn == conf->getConfFileName() && confxml )
buildDependsList( ic, *confxml );
else
{
UniXML xml(fn);
buildDependsList( ic, xml );
xml.close();
}
}
else if( !fname.empty() )
{
// оптимизация (не загружаем второй раз xml-файл)
if( fname == conf->getConfFileName() && confxml )
buildDependsList( ic, *confxml );
else
{
uxml.close();
uxml.open(fname);
buildDependsList(ic,uxml);
}
}
else if( confxml )
{
buildDependsList( ic, *confxml );
}
else
{
unideb[Debug::CRIT] << "(NCRestorer_XML:buildDependsList): configure xml-file not defined..." << endl;
}
}
// -----------------------------------------------------------------------------
void NCRestorer_XML::buildDependsList( IONotifyController* ic, UniXML& xml )
{
xmlNode* node;
if( (&xml) == conf->getConfXML() )
node = conf->getXMLSensorsSection();
else
node = xml.findNode(xml.getFirstNode(),"sensors");
if( node )
build_depends(xml, node, ic);
}
// -----------------------------------------------------------------------------
void NCRestorer_XML::build_depends( UniXML& xml, xmlNode* node, IONotifyController* ic )
{
UniXML_iterator it(node);
if( !it.goChildren() )
return;
for( ;it.getCurrent(); it.goNext() )
{
if( !check_list_item(it) )
continue;
xmlNode* dnode = find_node(xml,it,"depends","");
if( !dnode )
continue;
IOController::DependsInfo mydepinfo;
if( !getBaseInfo(xml,it,mydepinfo.si) )
continue;
UniSetTypes::KeyType k = UniSetTypes::key(mydepinfo.si.id,mydepinfo.si.node);
mydepinfo.it = ioFind(ic,k);
if( mydepinfo.it==ioEnd(ic) )
{
unideb[Debug::CRIT] << "(NCRestorer_XML:build_depends): Датчик "
<< xml.getProp(node,"name")
<< " НЕ НАЙДЕН ВО ВНУТРЕННЕМ СПИСКЕ! " << endl;
continue;
}
UniXML_iterator dit(dnode);
if( dit.goChildren() )
{
for( ;dit.getCurrent(); dit.goNext() )
{
if( !check_depend_item(dit) )
continue;
IOController::DependsInfo blk; // информации о блокировщике данного датчика
if( getDependsInfo(xml,dit,blk) )
{
k = UniSetTypes::key(blk.si.id,blk.si.node);
blk.it = ioFind(ic,k);
if( blk.it==ioEnd(ic) )
{
unideb[Debug::CRIT] << ic->getName() << "(NCRestorer_XML:build_depends): "
<< " Не найдена зависимость на " << xml.getProp(dit,"name")
<< " для " << xml.getProp(node,"name") << endl;
continue;
}
mydepinfo.block_invert = dit.getIntProp("block_invert");
long block_val = dit.getIntProp("block_value");
long defval = 0;
if( blk.it != ioEnd(ic) )
defval = blk.it->second.default_val;
// Проверка начальных условий для высталения блокировки
bool blk_set = defval ? false : true;
if( mydepinfo.block_invert )
blk_set ^= true;
if( mydepinfo.it!=ioEnd(ic) )
{
mydepinfo.it->second.blocked = blk_set;
mydepinfo.it->second.block_value = block_val;
if( blk_set )
{
mydepinfo.it->second.real_value = mydepinfo.it->second.value;
mydepinfo.it->second.value = block_val;
}
}
// вносим 'себя' в список зависимостей для указанного датчика
// (без проверки на дублирование
// т.к. не может быть два одинаковых ID
// в конф. файле...
if( blk.it != ioEnd(ic) )
{
blk.it->second.dlst.push_back(mydepinfo);
if( unideb.debugging(Debug::INFO) )
{
unideb[Debug::INFO] << ic->getName() << "(NCRestorer_XML:build_depends):"
<< " add " << xml.getProp(it,"name")
<< " to list of depends for " << xml.getProp(dit,"name")
<< " blk_set=" << blk_set
<< endl;
}
}
depslot(xml,dit,node);
}
}
}
}
}
// -----------------------------------------------------------------------------
bool NCRestorer_XML::check_depend_item( UniXML_iterator& it )
void NCRestorer_XML::setThresholdsFilter( const std::string& field, const std::string& val )
{
return UniSetTypes::check_filter(it,d_filterField,d_filterValue);
}
// ------------------------------------------------------------------------------------------
bool NCRestorer_XML::getDependsInfo( UniXML& xml, xmlNode* it, IOController::DependsInfo& di )
{
return getBaseInfo(xml,it,di.si);
t_filterField = field;
t_filterValue = val;
}
// -----------------------------------------------------------------------------
......@@ -7,7 +7,6 @@ libVarious_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libVarious_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
libVarious_la_SOURCES = DebugStream.cc Debug.cc UniXML.cc MessageType.cc Configuration.cc TextIndex.cc \
Restorer_XML.cc \
NCRestorer.cc NCRestorer_XML.cc \
RunLock.cc Mutex.cc SViewer.cc SMonitor.cc LT_Object.cc \
WDTInterface.cc \
CycleStorage.cc TableStorage.cc TableBlockStorage.cc
......
......@@ -90,6 +90,7 @@ bool Restorer_XML::getConsumerInfo( UniXML_iterator& it,
cid = conf->oind->getIdByName(cname);
if( cid == UniSetTypes::DefaultObjectId )
{
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << "(Restorer_XML:getConsumerInfo): НЕ НАЙДЕН ИДЕНТИФИКАТОР заказчика -->"
<< cname << endl;
return false;
......@@ -109,6 +110,7 @@ bool Restorer_XML::getConsumerInfo( UniXML_iterator& it,
if( cnode == UniSetTypes::DefaultObjectId )
{
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << "(Restorer_XML:getConsumerInfo): НЕ НАЙДЕН ИДЕНТИФИКАТОР узла -->"
<< cnodename << endl;
return false;
......@@ -137,6 +139,7 @@ bool Restorer_XML::old_getConsumerInfo( UniXML_iterator& it,
cid = conf->oind->getIdByName(cname);
if( cid == UniSetTypes::DefaultObjectId )
{
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << "(Restorer_XML:old_getConsumerInfo): НЕ НАЙДЕН ИДЕНТИФИКАТОР заказчика -->"
<< cname << endl;
return false;
......@@ -156,6 +159,7 @@ bool Restorer_XML::old_getConsumerInfo( UniXML_iterator& it,
if( cnode == UniSetTypes::DefaultObjectId )
{
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << "(Restorer_XML:old_getConsumerInfo): НЕ НАЙДЕН ИДЕНТИФИКАТОР узла -->"
<< cnodename << endl;
return false;
......
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