Commit 3d5326d8 authored by Pavel Vainerman's avatar Pavel Vainerman

(RRDStorage): предварительная версия, реализовал создание БД и

обновлений по таймеру.
parent de29e87d
#SUBDIRS=. tests
bin_PROGRAMS = UObject
UObject_SOURCES = UObject_SK.cc UObject.cc
bin_SCRIPTS = @PACKAGE@-codegen
UObject_SK.cc: UObject.src.xml
@UNISET_CODEGEN@ --ask -n UObject --topdir $(top_builddir)/ --no-main UObject.src.xml
xsldir = $(datadir)/uniset/xslt
xsl_DATA = *.xsl skel*
clean-local:
rm -rf *_SK.cc *_SK.h
all-local:
chmod 'a+x' @PACKAGE@-codegen
\ No newline at end of file
all-local: UObject_SK.cc UObject_SK.h
......@@ -9,8 +9,9 @@ test2_LDADD = $(top_builddir)/lib/libUniSet.la
test2_CXXFLAGS = -I$(top_builddir)/include
test2_SOURCES = TestGenAlone_SK.cc TestGenAlone.cc TestGenAlone-main.cc
GENERATED=TestGen_SK.h TestGen_SK.cc TestGen-main.cc
GENERATED=TestGen_SK.h TestGen_SK.cc TestGen-main.cc
GENERATED2=TestGenAlone_SK.h TestGenAlone_SK.cc TestGenAlone-main.cc
GENUOBJ=UObject_SK.cc UObject_SK.h
$(GENERATED): ../@PACKAGE@-codegen testgen.src.xml ../*.xsl
../@PACKAGE@-codegen -l $(top_builddir)/Utilities/codegen --local-include -n TestGen testgen.src.xml
......@@ -18,9 +19,12 @@ $(GENERATED): ../@PACKAGE@-codegen testgen.src.xml ../*.xsl
$(GENERATED2): ../@PACKAGE@-codegen testgen-alone.src.xml ../*.xsl
../@PACKAGE@-codegen -l $(top_builddir)/Utilities/codegen --local-include --alone -n TestGenAlone testgen-alone.src.xml
$(GENUOBJ): ../@PACKAGE@-codegen testgen.src.xml ../*.xsl
../@PACKAGE@-codegen -l $(top_builddir)/Utilities/codegen -n UObject --no-main uobject.src.xml
clean-local:
rm -rf $(GENERATED) $(GENERATED2)
rm -rf $(GENERATED) $(GENERATED2) $(GENUOBJ)
all-local: $(GENERATED) $(GENERATED2)
all-local: $(GENERATED) $(GENERATED2) $(GENUOBJ)
<?xml version="1.0" encoding="koi8-r"?>
<!--
name - название класса
msgcount - сколько сообщений обрабатывается за один раз
sleep_msec - пауза между итерациями в работе процесса
type
====
in - входные регистры (только для чтения)
out - выходные регистры (запись)
io - запись и чтение
-->
<Test>
<settings>
<set name="class-name" val="UObject"/>
<set name="msg-count" val="20"/>
<set name="sleep-msec" val="150"/>
<set name="arg-prefix" val=""/>
</settings>
<variables>
<!-- type = [int,str,bool,float]
int: max,min,no_range_exception=[0,1]
str:
float: max,min,no_range_exception=[0,1]
bool:
min - минимальное значение (может быть не задано)
max - максимальное значение (может быть не задано)
default - значение по умолчанию (может быть не задано)
no_range_exception=1 - при выходе за границы min или max только писать unideb[WARN].
-->
</variables>
<smap>
</smap>
<msgmap>
</msgmap>
</Test>
......@@ -121,6 +121,11 @@
<UNetExchange name="UNetExchange"/>
<HeartBeatTime time_msec="5000"/>
<TestGen input1_s="Input1_S" input2_s="DumpSensor1_S" name="TestGen" output1_c="DO_C"/>
<RRDStorage1 name="RRDStorage1">
<rrd filename="rrdtest.rrd" filter_field="rrd" filter_value="1" step="5" ds_field="rrd1_ds">
<item rra="RRA:AVERAGE:0.5:1:4320"/>
</rrd>
</RRDStorage1>
</settings>
<ObjectsMap idfromfile="1">
<!--
......@@ -193,7 +198,7 @@
<item id="51" iotype="DI" mbaddr="0x01" mbfunc="0x03" mbreg="0x01" ntit="1" mbtype="rtu" name="Input51_S" priority="Medium" rs="5" textname="Команда 2"/>
<item id="52" iotype="DI" mbaddr="0x01" mbfunc="0x06" mbreg="0x02" nbit="1" mbtype="rtu" name="Input52_S" priority="Medium" rs="5" textname="Команда 2"/>
<item id="53" iotype="DI" mbaddr="0x01" mbfunc="0x03" mbreg="0x01" nbit="2" mbtype="rtu" name="Input53_S" priority="Medium" rs="5" textname="Команда 2"/>
<item id="54" iotype="AI" name="AI54_S" textname="AI sensor 54" rrd="1" rrd1_ds="GAUGE:120:U:U"/>
</sensors>
<thresholds name="thresholds">
<sensor iotype="AI" name="AI_AS">
......@@ -230,6 +235,7 @@
<item id="6008" name="UNetExchange"/>
<item id="6009" name="MBMaster2"/>
<item id="6010" name="MBMultiMaster1"/>
<item id="6011" name="RRDStorage1"/>
</objects>
</ObjectsMap>
<messages idfromfile="1" name="messages">
......
......@@ -83,6 +83,25 @@ fi
AM_CONDITIONAL(DISABLE_MYSQL, test ${buildmysql} = false)
#check rrd support
AC_MSG_CHECKING([rrd support])
buildrrd=true
AC_ARG_ENABLE(rrd, AC_HELP_STRING([--disable-rrd], [disable RRD support]),
[ if test $enableval = yes; then buildrrd=true; else buildrrd=false; fi],[ buildrrd=true; ])
if test ${buildrrd} = true; then
AC_MSG_RESULT([enabled])
PKG_CHECK_MODULES(RRD,librrd)
AC_SUBST(RRD_LIBS)
AC_SUBST(RRD_CFLAGS)
else
AC_MSG_RESULT([disabled])
fi
AM_CONDITIONAL(DISABLE_RRD, test ${buildrrd} = false)
#check build extensions
ext=true
AC_MSG_CHECKING([Extensions])
......@@ -243,6 +262,8 @@ AC_CONFIG_FILES([Makefile
extensions/SharedMemory/Makefile
extensions/SharedMemory/libUniSetSharedMemory.pc
extensions/SharedMemoryPlus/Makefile
extensions/RRDStorage/Makefile
extensions/RRDStorage/libUniSetRRDStorage.pc
extensions/tests/Makefile
python/lib/Makefile
python/lib/pyUniSet/Makefile
......
......@@ -83,7 +83,7 @@
или \b bufferLastRemove="1", то терятся будут сообщения добавляемые в конец.
\section sec_DBS_Tables Таблицы SQLite
К основным таблицам относятся следующие:
К основным таблицам относятся следующие (описание в формате MySQL!):
\code
DROP TABLE IF EXISTS `main_history`;
CREATE TABLE `main_history` (
......
bin_PROGRAMS = @PACKAGE@-rrdstorage
RRD_VER=@LIBVER@
lib_LTLIBRARIES = libUniSetRRDStorage.la
libUniSetRRDStorage_la_LDFLAGS = -version-info $(RRD_VER)
libUniSetRRDStorage_la_LIBADD = $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS) $(RRD_LIBS)
libUniSetRRDStorage_la_CXXFLAGS = -I$(top_builddir)/extensions/include \
-I$(top_builddir)/extensions/SharedMemory \
$(SIGC_CFLAGS) $(RRD_CFLAGS)
libUniSetRRDStorage_la_SOURCES = RRDStorage.cc
@PACKAGE@_rrdstorage_SOURCES = main.cc
@PACKAGE@_rrdstorage_LDADD = libUniSetRRDStorage.la $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS) $(RRD_LIBS)
@PACKAGE@_rrdstorage_CXXFLAGS = -I$(top_builddir)/extensions/include \
-I$(top_builddir)/extensions/SharedMemory \
$(SIGC_CFLAGS) $(RRD_CFLAGS)
# install
devel_include_HEADERS = *.h
devel_includedir = $(pkgincludedir)/extensions
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libUniSetRRDStorage.pc
all-local:
ln -sf ../RRDStorage/$(devel_include_HEADERS) ../include
// -----------------------------------------------------------------------------
extern "C" {
#include <rrd.h>
}
#include <cmath>
#include <sstream>
#include "Exceptions.h"
#include "extensions/Extensions.h"
#include "RRDStorage.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
RRDStorage::RRDStorage( UniSetTypes::ObjectId objId, xmlNode* cnode, UniSetTypes::ObjectId shmId, SharedMemory* ic,
const string prefix ):
UObject_SK(objId,cnode),
shm( new SMInterface(shmId,&ui,objId,ic) ),
prefix(prefix)
{
UniXML::iterator it(cnode);
UniXML::iterator it1(cnode);
if( !it1.goChildren() )
{
ostringstream err;
err << myname << "(init): empty rrd list...";
RRDStorage::dlog[Debug::CRIT] << err.str() << endl;
throw NameNotFound(err.str());
}
int tmID=1;
for( ;it1.getCurrent(); it1++,tmID++ )
initRRD(it1,tmID);
}
// -----------------------------------------------------------------------------
RRDStorage::~RRDStorage()
{
}
// -----------------------------------------------------------------------------
void RRDStorage::step()
{
}
//--------------------------------------------------------------------------------
void RRDStorage::initRRD( xmlNode* cnode, int tmID )
{
UniXML::iterator it(cnode);
string fname( it.getProp("filename") );
string ff( it.getProp("filter_field") );
string fv( it.getProp("filter_value") );
string cf( it.getProp("ds_field") );
if( cf.empty() )
cf = ff+fv+"_ds";
int rrdstep = it.getPIntProp("step",5);
int lastup = it.getPIntProp("lastup",0);
RRDStorage::dlog[Debug::INFO] << myname << "(init): add rrd: file='" << fname
<< " " << ff << "='" << fv
<< "' create='" << cf << "'"
<< " step=" << rrdstep
<< endl;
std::list<std::string> rralist;
UniXML::iterator it_rra(cnode);
if( !it_rra.goChildren() )
{
ostringstream err;
err << myname << "(init): rrd='" << fname << "' Unknown RRA list";
RRDStorage::dlog[Debug::CRIT] << err.str();
throw SystemError(err.str());
}
for(;it_rra.getCurrent(); it_rra++ )
{
string rra( it_rra.getProp("rra") );
if( rra.empty() )
{
ostringstream err;
err << myname << "(init): rrd='" << fname << "' Unkown RRA item.. <item rra='...'";
RRDStorage::dlog[Debug::CRIT] << err.str();
throw SystemError(err.str());
}
rralist.push_back(rra);
}
if( rralist.empty() )
{
ostringstream err;
err << myname << "(init): Not found RRA items...";
RRDStorage::dlog[Debug::CRIT] << err.str() << endl;
throw SystemError(err.str());
}
// try
{
xmlNode* snode = conf->getXMLSensorsSection();
if(!snode)
{
ostringstream err;
err << myname << "(init): Not found section <sensors>";
RRDStorage::dlog[Debug::CRIT] << err.str();
throw SystemError(err.str());
}
UniXML_iterator it1(snode);
if( !it1.goChildren() )
{
ostringstream err;
err << myname << "(init): section <sensors> empty?!";
RRDStorage::dlog[Debug::CRIT] << err.str();
throw SystemError(err.str());
}
DSMap dsmap;
// список параметров входящих в RRD
std::list<std::string> dslist;
for(;it1.getCurrent(); it1.goNext() )
{
if( !UniSetTypes::check_filter(it1,ff,fv) )
continue;
std::string a(it1.getProp(cf));
if( a.empty() )
{
ostringstream err;
err << myname << "(init): Unknown create parameters ('" << cf << "')";
RRDStorage::dlog[Debug::CRIT] << err.str();
throw SystemError(err.str());
}
std::string dsname(it1.getProp("name"));
ostringstream nm;
nm << "DS:" << dsname << ":" << a;
dslist.push_back(nm.str());
ObjectId sid = conf->getSensorID( dsname );
if( sid == DefaultObjectId )
{
ostringstream err;
err << myname << "(init): Unknown SensorID for '" << dsname << "'";
RRDStorage::dlog[Debug::CRIT] << err.str();
throw SystemError(err.str());
}
DSInfo ds(dsname,it1.getIntProp("default"));
dsmap.insert( DSMap::value_type(sid,ds) );
}
if( dslist.empty() )
{
ostringstream err;
err << myname << "(init): Not found RRD items...";
RRDStorage::dlog[Debug::CRIT] << err.str() << endl;
throw SystemError(err.str());
}
char argc = dslist.size() + rralist.size();
char** argv = new char*[ argc ];
int k=0;
for( std::list<std::string>::iterator i=dslist.begin(); i!=dslist.end(); ++i,k++ )
argv[k] = strdup(i->c_str());
for( std::list<std::string>::iterator i=rralist.begin(); i!=rralist.end(); ++i,k++ )
argv[k] = strdup(i->c_str());
// for( k=0; k<argc; k++ )
// cout << "*** argv[" << k << "]='" << argv[k] << "'" << endl;
// Собственно создаём RRD
rrd_clear_error();
if( rrd_create_r(fname.c_str(),rrdstep,lastup,argc,(const char**)argv) < 0 )
{
ostringstream err;
err << myname << "(init): Can`t create RRD ('" << fname << "'): err: " << string(rrd_get_error());
RRDStorage::dlog[Debug::CRIT] << err.str() << endl;
throw SystemError(err.str());
}
// Чистим выделенную память
for( k=0; k<argc; k++ )
free( argv[k] );
delete[] argv;
RRDInfo rrd(fname,tmID,rrdstep,dsmap);
rrdlist.push_back(rrd);
}
/* catch( Exception& ex )
{
RRDStorage::dlog[Debug::CRIT] << myname << "(init) " << ex << std::endl;
}
catch( ... )
{
RRDStorage::dlog[Debug::CRIT] << myname << "(init): catch ..." << std::endl;
}
*/
}
//--------------------------------------------------------------------------------
void RRDStorage::help_print( int argc, const char* const* argv )
{
cout << "--rrdstorage-name - ID for rrdstorage. Default: RRDStorage1. " << endl;
cout << "--rrdstorage-locale name - DB locale. Default: koi8-r. " << endl;
cout << "--rrdstorage-heartbeat-id name - ID for heartbeat sensor." << endl;
cout << "--rrdstorage-heartbeat-max val - max value for heartbeat sensor." << endl;
}
// -----------------------------------------------------------------------------
RRDStorage* RRDStorage::init_rrdstorage( int argc, const char* const* argv,
UniSetTypes::ObjectId icID, SharedMemory* ic,
const std::string prefix )
{
string name = conf->getArgParam("--" + prefix + "-name","RRDStorage");
if( name.empty() )
{
UniSetExtensions::dlog[Debug::CRIT] << "(RRDStorage): Unknown name. Usage: --" << prefix << "-name" << endl;
return 0;
}
ObjectId ID = conf->getObjectID(name);
if( ID == UniSetTypes::DefaultObjectId )
{
UniSetExtensions::dlog[Debug::CRIT] << "(RRDStorage): Not found ID for '" << name
<< " in '" << conf->getObjectsSection() << "' section" << endl;
return 0;
}
string confname = conf->getArgParam("--" + prefix + "-confnode",name);
xmlNode* cnode = conf->getNode(confname);
if( !cnode )
{
UniSetExtensions::dlog[Debug::CRIT] << "(RRDStorage): " << name << "(init): Not found <" + confname + ">" << endl;
return 0;
}
UniSetExtensions::dlog[Debug::INFO] << "(RRDStorage): name = " << name << "(" << ID << ")" << endl;
return new RRDStorage(ID,cnode,icID,ic,prefix);
}
// -----------------------------------------------------------------------------
void RRDStorage::askSensors( UniversalIO::UIOCommand cmd )
{
UObject_SK::askSensors(cmd);
for( RRDList::iterator it=rrdlist.begin(); it!=rrdlist.end(); ++it )
{
for( DSMap::iterator s=it->dsmap.begin(); s!=it->dsmap.end(); ++s )
{
try
{
shm->askSensor(s->first,cmd);
}
catch( std::exception& ex )
{
RRDStorage::dlog[Debug::CRIT] << myname << "(askSensors): " << ex.what() << endl;
}
}
}
}
// -----------------------------------------------------------------------------
void RRDStorage::sysCommand( UniSetTypes::SystemMessage* sm )
{
UObject_SK::sysCommand(sm);
if( sm->command == SystemMessage::StartUp || sm->command == SystemMessage::WatchDog )
{
for( RRDList::iterator it=rrdlist.begin(); it!=rrdlist.end(); ++it )
{
try
{
askTimer(it->tid,it->sec*1000);
}
catch( std::exception& ex )
{
RRDStorage::dlog[Debug::CRIT] << myname << "(askTimer): " << ex.what() << endl;
}
}
}
}
// -----------------------------------------------------------------------------
void RRDStorage::sensorInfo( UniSetTypes::SensorMessage* sm )
{
}
// -----------------------------------------------------------------------------
void RRDStorage::timerInfo( UniSetTypes::TimerMessage* tm )
{
for( RRDList::iterator it=rrdlist.begin(); it!=rrdlist.end(); ++it )
{
if( it->tid == tm->id )
{
ostringstream v;
v << time(0);
for( DSMap::iterator s=it->dsmap.begin(); s!=it->dsmap.end(); ++s )
v << ":" << s->second.value;
if( RRDStorage::dlog.debugging(Debug::INFO) )
RRDStorage::dlog[Debug::INFO] << myname << "(update): '" << it->filename << "' " << v.str() << endl;
rrd_clear_error();
const char* argv = v.str().c_str();
if( rrd_update_r(it->filename.c_str(),NULL,1,&argv) < 0 )
{
ostringstream err;
err << myname << "(update): Can`t update RRD ('" << it->filename << "'): err: " << string(rrd_get_error());
RRDStorage::dlog[Debug::CRIT] << err.str() << endl;
}
break;
}
}
}
// -----------------------------------------------------------------------------
#ifndef _RRDStorage_H_
#define _RRDStorage_H_
// -----------------------------------------------------------------------------
#include "UObject_SK.h"
#include "SMInterface.h"
#include "SharedMemory.h"
// -----------------------------------------------------------------------------
/*!
*/
class RRDStorage:
public UObject_SK
{
public:
RRDStorage( UniSetTypes::ObjectId objId, xmlNode* cnode, UniSetTypes::ObjectId shmID, SharedMemory* ic=0,
const std::string prefix="rrd" );
virtual ~RRDStorage();
/*! глобальная функция для инициализации объекта */
static RRDStorage* init_rrdstorage( int argc, const char* const* argv,
UniSetTypes::ObjectId shmID, SharedMemory* ic=0,
const std::string prefix="rrd" );
/*! глобальная функция для вывода help-а */
static void help_print( int argc, const char* const* argv );
protected:
RRDStorage();
virtual void askSensors( UniversalIO::UIOCommand cmd );
virtual void sensorInfo( UniSetTypes::SensorMessage* sm );
virtual void timerInfo( UniSetTypes::TimerMessage* tm );
virtual void sysCommand( UniSetTypes::SystemMessage* sm );
virtual void initRRD( xmlNode* cnode, int tmID );
void step();
SMInterface* shm;
struct DSInfo
{
std::string dsname;
long value;
DSInfo( const std::string& dsname, long defval ):
dsname(dsname),value(defval){}
};
typedef std::map<UniSetTypes::ObjectId,DSInfo> DSMap;
struct RRDInfo
{
std::string filename;
long tid;
long sec;
DSMap dsmap;
RRDInfo( const std::string& fname, long tmID, long sec, const DSMap& ds ):
filename(fname),tid(tmID),sec(sec),dsmap(ds){}
};
typedef std::list<RRDInfo> RRDList;
RRDList rrdlist;
private:
std::string prefix;
};
// -----------------------------------------------------------------------------
#endif // _RRDStorage_H_
// -----------------------------------------------------------------------------
#!/bin/sh
ln -s -f ../../Utilities/scripts/uniset-start.sh
ln -s -f ../../Utilities/scripts/uniset-stop.sh stop.sh
ln -s -f ../../Utilities/scripts/uniset-functions.sh
ln -s -f ../../conf/test.xml test.xml
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libUniSetRRDStorage
Description: Support library for UniSetRRDStorage
Requires: libUniSetExtensions librrd
Version: @VERSION@
Libs: -L${libdir} -lUniSetRRDStorage
Cflags: -I${includedir}/uniset
#include <sstream>
#include "RRDStorage.h"
#include "Configuration.h"
#include "Debug.h"
#include "ObjectsActivator.h"
#include "Extensions.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
int main( int argc, const char** argv )
{
if( argc>1 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) )
{
cout << "--smemory-id objectName - SharedMemory objectID. Default: autodetect" << endl;
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
cout << "--rrdstorage-logfile filename - logfilename. Default: rrdstorage.log" << endl;
cout << endl;
RRDStorage::help_print(argc, argv);
return 0;
}
try
{
string confile=UniSetTypes::getArgParam("--confile",argc, argv, "configure.xml");
conf = new Configuration( argc, argv, confile );
string logfilename(conf->getArgParam("--rrdstorage-logfile"));
if( logfilename.empty() )
logfilename = "rrdstorage.log";
conf->initDebug(dlog,"dlog");
std::ostringstream logname;
string dir(conf->getLogDir());
logname << dir << logfilename;
unideb.logFile( logname.str() );
dlog.logFile( logname.str() );
ObjectId shmID = DefaultObjectId;
string sID = conf->getArgParam("--smemory-id");
if( !sID.empty() )
shmID = conf->getControllerID(sID);
else
shmID = getSharedMemoryID();
if( shmID == DefaultObjectId )
{
cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
return 1;
}
RRDStorage* db = RRDStorage::init_rrdstorage(argc,argv,shmID);
if( !db )
{
dlog[Debug::CRIT] << "(rrdstorage): init не прошёл..." << endl;
return 1;
}
db->init_dlog(dlog);
ObjectsActivator act;
act.addObject(static_cast<class UniSetObject*>(db));
SystemMessage sm(SystemMessage::StartUp);
act.broadcast( sm.transport_msg() );
unideb(Debug::ANY) << "\n\n\n";
unideb[Debug::ANY] << "(main): -------------- RRDStorage START -------------------------\n\n";
dlog(Debug::ANY) << "\n\n\n";
dlog[Debug::ANY] << "(main): -------------- RRDStorage START -------------------------\n\n";
act.run(false);
return 0;
}
catch( UniSetTypes::Exception& ex )
{
dlog[Debug::CRIT] << "(rrdstorage): " << ex << std::endl;
}
catch(...)
{
dlog[Debug::CRIT] << "(rrdstorage): catch ..." << std::endl;
}
return 1;
}
#!/bin/sh
uniset-start.sh -f ./uniset-rrdstorage --confile test.xml \
--rrd-name RRDStorage1 \
--dlog-add-levels info,crit,warn
// --------------------------------------------------------------------------
/*
DO NOT EDIT THIS FILE. IT IS AUTOGENERATED FILE.
ALL YOUR CHANGES WILL BE LOST.
НЕ РЕДАКТИРУЙТЕ ЭТОТ ФАЙЛ. ЭТОТ ФАЙЛ СОЗДАН АВТОМАТИЧЕСКИ.
ВСЕ ВАШИ ИЗМЕНЕНИЯ БУДУТ ПОТЕРЯНЫ.
*/
// --------------------------------------------------------------------------
// generate timestamp: 2013-12-10+04:00
// -----------------------------------------------------------------------------
#ifndef UObject_SK_H_
#define UObject_SK_H_
// -----------------------------------------------------------------------------
#include <string>
#include "UniSetObject.h"
#include "LT_Object.h"
#include "UniXML.h"
#include "Trigger.h"
#include "SMInterface.h"
#include "DebugStream.h"
// -----------------------------------------------------------------------------
class UObject_SK:
public UniSetObject,
public LT_Object
{
public:
UObject_SK( UniSetTypes::ObjectId id, xmlNode* node=UniSetTypes::conf->getNode("UObject"),
UniSetTypes::ObjectId shmID = UniSetTypes::DefaultObjectId );
UObject_SK( UniSetTypes::ObjectId id, xmlNode* node=UniSetTypes::conf->getNode("UObject"), const std::string& argprefix="" );
UObject_SK();
virtual ~UObject_SK();
......@@ -22,36 +33,57 @@ class UObject_SK:
bool alarm( UniSetTypes::ObjectId sid, bool state );
bool getState( UniSetTypes::ObjectId sid );
long getValue( UniSetTypes::ObjectId sid );
void setValue( UniSetTypes::ObjectId sid, long value );
void setState( UniSetTypes::ObjectId sid, bool state );
void askState( UniSetTypes::ObjectId sid, UniversalIO::UIOCommand );
void askValue( UniSetTypes::ObjectId sid, UniversalIO::UIOCommand );
void askThreshold ( UniSetTypes::ObjectId sensorId, UniSetTypes::ThresholdId tid,
UniversalIO::UIOCommand cmd,
CORBA::Long lowLimit, CORBA::Long hiLimit, CORBA::Long sensibility,
UniSetTypes::ObjectId backid = UniSetTypes::DefaultObjectId );
void askState( UniSetTypes::ObjectId sid, UniversalIO::UIOCommand, UniSetTypes::ObjectId node = UniSetTypes::conf->getLocalNode() );
void askValue( UniSetTypes::ObjectId sid, UniversalIO::UIOCommand, UniSetTypes::ObjectId node = UniSetTypes::conf->getLocalNode() );
void updateValues();
void setInfo( UniSetTypes::ObjectId code, bool state );
void setMsg( UniSetTypes::ObjectId code, bool state );
DebugStream dlog;
void init_dlog(DebugStream& dlog);
// Используемые идентификаторы
// Используемые идентификаторы сообщений
// Текущее значение и предыдущее значение
// --- public variables ---
// --- end of public variables ---
protected:
// --- protected variables ---
// ---- end of protected variables ----
virtual void callback();
virtual void processingMessage( UniSetTypes::VoidMessage* msg );
virtual void sysCommand( UniSetTypes::SystemMessage* sm );
virtual void askSensors( UniversalIO::UIOCommand cmd );
virtual void sensorInfo( UniSetTypes::SensorMessage* sm ){};
virtual void timerInfo( UniSetTypes::TimerMessage* tm ){};
virtual void askSensors( UniversalIO::UIOCommand cmd ){}
virtual void sensorInfo( UniSetTypes::SensorMessage* sm ){}
virtual void timerInfo( UniSetTypes::TimerMessage* tm ){}
virtual void sigterm( int signo );
virtual bool activateObject();
virtual void testMode( bool state );
void updatePreviousValues();
void checkSensors();
void updateOutputs( bool force );
bool checkTestMode();
void preAskSensors( UniversalIO::UIOCommand cmd );
void preSensorInfo( UniSetTypes::SensorMessage* sm );
void preTimerInfo( UniSetTypes::TimerMessage* tm );
void waitSM( int wait_msec );
void waitSM( int wait_msec, UniSetTypes::ObjectId testID = UniSetTypes::DefaultObjectId );
void resetMsg();
Trigger trResetMsg;
......@@ -63,24 +95,37 @@ class UObject_SK:
int sleep_msec; /*!< пауза между итерациями */
bool active;
bool isTestMode;
Trigger trTestMode;
UniSetTypes::ObjectId idTestMode_S; /*!< идентификатор для флага тестовго режима (для всех) */
UniSetTypes::ObjectId idLocalTestMode_S; /*!< идентификатор для флага тестовго режима (для данного узла) */
bool in_TestMode_S;
bool in_LocalTestMode_S;
UniSetTypes::ObjectId smTestID; /*!< идентификатор датчика для тестирования готовности SM */
// управление датчиком "сердцебиения"
PassiveTimer ptHeartBeat; /*! < период "сердцебиения" */
UniSetTypes::ObjectId idHeartBeat; /*! < идентификатор датчика (AI) "сердцебиения" */
int maxHeartBeat; /*! < сохраняемое значение */
xmlNode* confnode;
SMInterface shm;
/*! получить числовое свойство из конф. файла по привязанной confnode */
int getIntProp(const std::string& name) { return UniSetTypes::conf->getIntProp(confnode, name); }
/*! получить текстовое свойство из конф. файла по привязанной confnode */
inline const std::string getProp(const std::string& name) { return UniSetTypes::conf->getProp(confnode, name); }
int smReadyTimeout; /*!< время ожидания готовности SM */
bool activated;
int activateTimeout; /*!< время ожидания готовности UniSetObject к работе */
PassiveTimer ptStartUpTimeout; /*!< время на блокировку обработки WatchDog, если недавно был StartUp */
int askPause; /*!< пауза между неудачными попытками заказать датчики */
IOController_i::SensorInfo si;
private:
IOController_i::SensorInfo si;
// --- private variables ---
// --- end of private variables ---
bool end_private; // вспомогательное поле (для внутреннего использования при генерировании кода)
};
// -----------------------------------------------------------------------------
......
......@@ -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 UObject_SK.cc
#UObject_SK.cc
\ No newline at end of file
// Метод с использованием заказа датчиков
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
/*
DO NOT EDIT THIS FILE. IT IS AUTOGENERATED FILE.
ALL YOUR CHANGES WILL BE LOST.
НЕ РЕДАКТИРУЙТЕ ЭТОТ ФАЙЛ. ЭТОТ ФАЙЛ СОЗДАН АВТОМАТИЧЕСКИ.
ВСЕ ВАШИ ИЗМЕНЕНИЯ БУДУТ ПОТЕРЯНЫ.
*/
// --------------------------------------------------------------------------
// generate timestamp: 2013-12-10+04:00
// -----------------------------------------------------------------------------
#include "Configuration.h"
#include "Exceptions.h"
#include "Extensions.h"
#include "UObject_SK.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
// --------------------------------------------------------------------------
// -----------------------------------------------------------------------------
UObject_SK::UObject_SK():
// Инициализация идентификаторов (имена берутся из конф. файла)
// Используемые идентификаторы сообщений (имена берутся из конф. файла)
// variables
active(false),
isTestMode(false),
idTestMode_S(DefaultObjectId),
idLocalTestMode_S(DefaultObjectId),
idHeartBeat(DefaultObjectId),
maxHeartBeat(10),
confnode(0),
shm(DefaultObjectId,&ui,DefaultObjectId),
smReadyTimeout(0),
activated(false)
activated(false),
askPause(2000),
end_private(false)
{
dlog[Debug::CRIT] << "UObject: init failed!!!!!!!!!!!!!!!" << endl;
unideb[Debug::CRIT] << "UObject: init failed!!!!!!!!!!!!!!!" << endl;
throw Exception( string(myname+": init failed!!!") );
}
// -----------------------------------------------------------------------------
UObject_SK::UObject_SK( ObjectId id, xmlNode* cnode, ObjectId shmID ):
// ( val, confval, default val )
static const std::string init3_str( const std::string& s1, const std::string& s2, const std::string& s3 )
{
if( !s1.empty() )
return s1;
if( !s2.empty() )
return s2;
return s3;
}
// -----------------------------------------------------------------------------
UObject_SK::UObject_SK( ObjectId id, xmlNode* cnode, const std::string& argprefix ):
UniSetObject(id),
sleep_msec(200),
// Инициализация идентификаторов (имена берутся из конф. файла)
// Используемые идентификаторы сообщений (имена берутся из конф. файла)
// variables
sleep_msec(150),
active(true),
isTestMode(false),
idTestMode_S(conf->getSensorID("TestMode_S")),
idLocalTestMode_S(conf->getSensorID(conf->getProp(cnode,"LocalTestMode_S"))),
in_TestMode_S(false),
in_LocalTestMode_S(false),
idHeartBeat(DefaultObjectId),
maxHeartBeat(10),
confnode(cnode),
shm(shmID,&ui,id),
smReadyTimeout(0),
activated(false)
activated(false),
askPause(conf->getPIntProp(cnode,"askPause",2000)),
end_private(false)
{
si.node = conf->getLocalNode();
if( UniSetTypes::findArgParam("--print-id-list",conf->getArgc(),conf->getArgv()) != -1 )
{
// abort();
}
if( getId() == DefaultObjectId )
{
ostringstream err;
err << "(UObject::init): Unknown ObjectID!";
throw SystemError( err.str() );
}
sleep_msec = conf->getArgPInt("--sleep-msec", 200);
UniXML_iterator it(cnode);
string heart = conf->getArgParam("--heartbeat-id",it.getProp("heartbeat_id"));
if( !heart.empty() )
{
idHeartBeat = conf->getSensorID(heart);
if( idHeartBeat == DefaultObjectId )
{
ostringstream err;
err << myname << ": не найден идентификатор для датчика 'HeartBeat' " << heart;
throw SystemError(err.str());
}
int heartbeatTime = conf->getArgPInt("--heartbeat-time",it.getProp("heartbeatTime"),conf->getHeartBeatTime());
if( heartbeatTime>0 )
ptHeartBeat.setTiming(heartbeatTime);
else
ptHeartBeat.setTiming(UniSetTimer::WaitUpTime);
maxHeartBeat = conf->getArgPInt("--heartbeat-max",it.getProp("heartbeat_max"), 10);
}
// Инициализация значений
sleep_msec = conf->getArgPInt("--sleep-msec","150", 150);
resetMsgTime = conf->getPIntProp(cnode,"resetMsgTime", 200);
resetMsgTime = conf->getPIntProp(cnode,"resetMsgTime", 2000);
ptResetMsg.setTiming(resetMsgTime);
smReadyTimeout = conf->getArgInt("--sm-ready-timeout","");
......@@ -49,42 +130,63 @@ activated(false)
else if( smReadyTimeout < 0 )
smReadyTimeout = UniSetTimer::WaitUpTime;
std::string tmp_smtestID("");
smTestID = conf->getSensorID(init3_str(conf->getArgParam("--" + argprefix + "sm-test-id"),conf->getProp(cnode,"smTestID"),tmp_smtestID));
activateTimeout = conf->getArgPInt("--activate-timeout", 20000);
timeout_t msec = conf->getArgPInt("--startup-timeout", 10000);
int msec = conf->getArgPInt("--startup-timeout", 10000);
ptStartUpTimeout.setTiming(msec);
// ===================== <variables> =====================
// ===================== end of <variables> =====================
}
// -----------------------------------------------------------------------------
UObject_SK::~UObject_SK()
{
}
// -----------------------------------------------------------------------------
void UObject_SK::updateValues()
{
in_TestMode_S = (idTestMode_S!=DefaultObjectId) ? shm.getState(idTestMode_S):false;
in_LocalTestMode_S = (idLocalTestMode_S!=DefaultObjectId) ? shm.getState(idLocalTestMode_S):false;
// Опрашиваем все входы...
}
// -----------------------------------------------------------------------------
bool UObject_SK::alarm( UniSetTypes::ObjectId code, bool state )
void UObject_SK::updatePreviousValues()
{
if( code == UniSetTypes::DefaultObjectId )
}
// -----------------------------------------------------------------------------
void UObject_SK::checkSensors()
{
}
// -----------------------------------------------------------------------------
bool UObject_SK::alarm( UniSetTypes::ObjectId _code, bool _state )
{
if( _code == UniSetTypes::DefaultObjectId )
{
dlog[Debug::CRIT] << getName()
unideb[Debug::CRIT] << getName()
<< "(alarm): попытка послать сообщение с DefaultObjectId"
<< endl;
return false;
}
dlog[Debug::LEVEL1] << getName() << "(alarm): ";
if( state )
dlog(Debug::LEVEL1) << "SEND ";
unideb[Debug::LEVEL1] << getName() << "(alarm): ";
if( _state )
unideb(Debug::LEVEL1) << "SEND ";
else
dlog(Debug::LEVEL1) << "RESET ";
unideb(Debug::LEVEL1) << "RESET ";
unideb(Debug::LEVEL1) << endl;
dlog(Debug::INFO) << " not found MessgeOID?!!" << endl;
unideb[Debug::LEVEL1] << " not found MessgeOID?!!" << endl;
return false;
}
// -----------------------------------------------------------------------------
......@@ -94,36 +196,48 @@ void UObject_SK::resetMsg()
}
// -----------------------------------------------------------------------------
void UObject_SK::testMode( bool state )
void UObject_SK::testMode( bool _state )
{
if( !state )
if( !_state )
return;
// отключаем все выходы
}
// -----------------------------------------------------------------------------
void UObject_SK::processingMessage( UniSetTypes::VoidMessage* msg )
// --------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------
void UObject_SK::init_dlog( DebugStream& d )
{
UObject_SK::dlog = d;
}
// ------------------------------------------------------------------------------------------
void UObject_SK::processingMessage( UniSetTypes::VoidMessage* _msg )
{
try
{
switch( msg->type )
switch( _msg->type )
{
case Message::SensorInfo:
{
SensorMessage sm( msg );
sensorInfo( &sm );
SensorMessage _sm( _msg );
preSensorInfo( &_sm );
break;
}
case Message::Timer:
{
TimerMessage tm(msg);
preTimerInfo(&tm);
TimerMessage _tm(_msg);
preTimerInfo(&_tm);
break;
}
case Message::SysCommand:
{
SystemMessage sm( msg );
sysCommand( &sm );
SystemMessage _sm( _msg );
sysCommand( &_sm );
break;
}
......@@ -137,17 +251,61 @@ void UObject_SK::processingMessage( UniSetTypes::VoidMessage* msg )
}
}
// -----------------------------------------------------------------------------
void UObject_SK::setState( UniSetTypes::ObjectId sid, bool state )
void UObject_SK::sysCommand( SystemMessage* _sm )
{
#warning сделать setState отдельной функцией, а не через setValue
setValue(sid, state ? 1 : 0 );
switch( _sm->command )
{
case SystemMessage::WatchDog:
unideb << myname << "(sysCommand): WatchDog" << endl;
if( !active || !ptStartUpTimeout.checkTime() )
{
unideb[Debug::WARN] << myname << "(sysCommand): игнорируем WatchDog, потому-что только-что стартанули" << endl;
break;
}
case SystemMessage::StartUp:
{
waitSM(smReadyTimeout);
ptStartUpTimeout.reset();
// т.к. для io-переменных важно соблюдать последовательность!
// сперва обновить входы.. а потом уже выходы
updateValues();
updateOutputs(true); // принудительное обновление выходов
preAskSensors(UniversalIO::UIONotify);
askSensors(UniversalIO::UIONotify);
active = true;
break;
}
case SystemMessage::FoldUp:
case SystemMessage::Finish:
preAskSensors(UniversalIO::UIODontNotify);
askSensors(UniversalIO::UIODontNotify);
break;
case SystemMessage::LogRotate:
{
// переоткрываем логи
unideb << myname << "(sysCommand): logRotate" << endl;
string fname = unideb.getLogFile();
if( !fname.empty() )
{
unideb.logFile(fname.c_str());
unideb << myname << "(sysCommand): ***************** UNIDEB LOG ROTATE *****************" << endl;
}
}
break;
default:
break;
}
}
// -----------------------------------------------------------------------------
bool UObject_SK::checkTestMode()
void UObject_SK::setState( UniSetTypes::ObjectId _sid, bool _state )
{
return (in_TestMode_S && in_LocalTestMode_S);
setValue(_sid, _state ? 1 : 0 );
}
// -----------------------------------------------------------------------------
void UObject_SK::sigterm( int signo )
{
UniSetObject::sigterm(signo);
......@@ -168,48 +326,43 @@ bool UObject_SK::activateObject()
return true;
}
// -----------------------------------------------------------------------------
void UObject_SK::askThreshold( UniSetTypes::ObjectId sid, UniSetTypes::ThresholdId tid,
UniversalIO::UIOCommand cmd,
CORBA::Long lowLimit, CORBA::Long hiLimit, CORBA::Long sensibility,
UniSetTypes::ObjectId backid )
void UObject_SK::preTimerInfo( UniSetTypes::TimerMessage* _tm )
{
#warning askThreshold НЕ РЕАЛИЗОВАНА...
// shm.askThreshold( sid,tid,cmd,lowLimit,hiLimit,sensibility,backid);
}
// -----------------------------------------------------------------------------
void UObject_SK::preTimerInfo( UniSetTypes::TimerMessage* tm )
{
timerInfo(tm);
timerInfo(_tm);
}
// ----------------------------------------------------------------------------
void UObject_SK::waitSM( int wait_msec )
void UObject_SK::waitSM( int wait_msec, ObjectId _testID )
{
if( !shm.waitSMready(wait_msec) )
if( _testID == DefaultObjectId )
_testID = smTestID;
if( _testID == DefaultObjectId )
return;
if( unideb.debugging(Debug::INFO) )
{
unideb[Debug::INFO] << myname << "(waitSM): waiting SM ready "
<< wait_msec << " msec"
<< " testID=" << _testID << endl;
}
if( !ui.waitReady(_testID,wait_msec) )
{
ostringstream err;
err << myname
<< "(waitSM): Не дождались готовности(exist) SharedMemory к работе в течение "
<< wait_msec << " мсек";
dlog[Debug::CRIT] << err.str() << endl;
kill(SIGTERM,getpid()); // прерываем (перезапускаем) процесс...
unideb[Debug::CRIT] << err.str() << endl;
terminate();
abort();
// kill(SIGTERM,getpid()); // прерываем (перезапускаем) процесс...
throw SystemError(err.str());
}
if( idTestMode_S != DefaultObjectId )
{
if( !shm.waitSMworking(idTestMode_S,wait_msec) )
{
ostringstream err;
err << myname
<< "(waitSM): Не дождались готовности(work) SharedMemory к работе в течение "
<< wait_msec << " мсек";
dlog[Debug::CRIT] << err.str() << endl;
kill(SIGTERM,getpid()); // прерываем (перезапускаем) процесс...
throw SystemError(err.str());
}
}
}
// ----------------------------------------------------------------------------
......@@ -219,25 +372,11 @@ void UObject_SK::callback()
if( !active )
return;
try
{
#warning Сделать работу с TestMode на основе заказа!
isTestMode = checkTestMode();
if( trTestMode.change(isTestMode) )
testMode(isTestMode);
if( isTestMode )
{
if( !active )
return;
msleep( sleep_msec );
return;
}
{
// проверка таймеров
checkTimers(this);
#warning Сделать работу с ResetMsg на основе askTimer!
if( resetMsgTime>0 && trResetMsg.hi(ptResetMsg.checkTime()) )
{
// cout << myname << ": ********* reset messages *********" << endl;
......@@ -245,34 +384,41 @@ void UObject_SK::callback()
}
// обработка сообщений (таймеров и т.п.)
for( int i=0; i<30; i++ )
for( int i=0; i<20; i++ )
{
if( !receiveMessage(msg) )
break;
processingMessage(&msg);
updateOutputs(false);
updatePreviousValues();
// updatePreviousValues();
}
// Выполнение шага программы
step();
// "сердцебиение"
if( idHeartBeat!=DefaultObjectId && ptHeartBeat.checkTime() )
{
ui.saveValue(idHeartBeat,maxHeartBeat,UniversalIO::AnalogInput);
ptHeartBeat.reset();
}
// обновление выходов
updateOutputs(false);
updatePreviousValues();
}
catch( Exception& ex )
{
dlog[Debug::CRIT] << myname << "(execute): " << ex << endl;
unideb[Debug::CRIT] << myname << "(execute): " << ex << endl;
}
catch(CORBA::SystemException& ex)
{
dlog[Debug::CRIT] << myname << "(execute): СORBA::SystemException: "
unideb[Debug::CRIT] << myname << "(execute): СORBA::SystemException: "
<< ex.NP_minorString() << endl;
}
catch(...)
{
dlog[Debug::CRIT] << myname << "(execute): catch ..." << endl;
unideb[Debug::CRIT] << myname << "(execute): catch ..." << endl;
}
if( !active )
......@@ -281,63 +427,105 @@ void UObject_SK::callback()
msleep( sleep_msec );
}
// -----------------------------------------------------------------------------
void UObject_SK::askState( UniSetTypes::ObjectId sid, UniversalIO::UIOCommand cmd )
void UObject_SK::setValue( UniSetTypes::ObjectId _sid, long _val )
{
// ui.setState(sid,state);
}
// -----------------------------------------------------------------------------
void UObject_SK::updateOutputs( bool _force )
{
shm.askSensor(sid,cmd,getId());
}
// -----------------------------------------------------------------------------
void UObject_SK::askValue( UniSetTypes::ObjectId sid, UniversalIO::UIOCommand cmd )
void UObject_SK::preSensorInfo( UniSetTypes::SensorMessage* _sm )
{
shm.askSensor(sid,cmd,getId());
sensorInfo(_sm);
}
// -----------------------------------------------------------------------------
void UObject_SK::askSensors( UniversalIO::UIOCommand cmd )
void UObject_SK::askState( UniSetTypes::ObjectId _sid, UniversalIO::UIOCommand _cmd, UniSetTypes::ObjectId _node )
{
ui.askRemoteSensor(_sid,_cmd,_node,getId());
}
// -----------------------------------------------------------------------------
void UObject_SK::askValue( UniSetTypes::ObjectId _sid, UniversalIO::UIOCommand _cmd, UniSetTypes::ObjectId _node )
{
ui.askRemoteSensor(_sid,_cmd,_node,getId());
}
// -----------------------------------------------------------------------------
bool UObject_SK::getState( UniSetTypes::ObjectId _sid )
{
return (bool)getValue(_sid);
}
// -----------------------------------------------------------------------------
long UObject_SK::getValue( UniSetTypes::ObjectId _sid )
{
try
{
unideb[Debug::CRIT] << myname << "(getState): Обращение к неизвестному ДИСКРЕТНОМУ датчику sid="
<< _sid << endl;
}
catch(Exception& ex)
{
unideb[Debug::CRIT] << myname << "(getState): " << ex << endl;
throw;
}
return 0;
}
// -----------------------------------------------------------------------------
void UObject_SK::preAskSensors( UniversalIO::UIOCommand _cmd )
{
PassiveTimer ptAct(activateTimeout);
while( !activated && !ptAct.checkTime() )
{
cout << myname << "(askSensors): wait activate..." << endl;
cout << myname << "(preAskSensors): wait activate..." << endl;
msleep(300);
if( activated )
break;
}
if( !activated )
dlog[Debug::CRIT] << myname
<< "(askSensors): ************* don`t activated?! ************" << endl;
unideb[Debug::CRIT] << myname
<< "(preAskSensors): ************* don`t activated?! ************" << endl;
for( ;; )
{
try
{
//
return;
}
catch(SystemError& err)
{
dlog[Debug::CRIT] << myname << "(askSensors): " << err << endl;
unideb[Debug::CRIT] << myname << "(preAskSensors): " << err << endl;
}
catch(Exception& ex)
{
dlog[Debug::CRIT] << myname << "(askSensors): " << ex << endl;
unideb[Debug::CRIT] << myname << "(preAskSensors): " << ex << endl;
}
catch(...)
{
dlog[Debug::CRIT] << myname << "(askSensors): catch(...)" << endl;
unideb[Debug::CRIT] << myname << "(preAskSensors): catch(...)" << endl;
}
#warning Сделать паузу между заказами настраиваемой из конф. файла
msleep(2000);
msleep(askPause);
}
}
// -----------------------------------------------------------------------------
void UObject_SK::setInfo( UniSetTypes::ObjectId code, bool state )
void UObject_SK::setMsg( UniSetTypes::ObjectId _code, bool _state )
{
alarm( code, state );
if( state )
// блокируем сброс (т.к. он автоматически по таймеру)
if( !_state )
{
#warning Сделать время настраиваемым
msleep(50); // сбрасываем сразу...
alarm( code, false );
ptResetMsg.reset();
return;
}
alarm( _code, _state );
ptResetMsg.reset();
}
// ----------------------------------------------------------------------------
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