Commit ae278e5f authored by Pavel Vainerman's avatar Pavel Vainerman

(smonit): Реализация вывода информации о том, кто менял датчик,

поменял форматирование вывода. (uniset-admin): ввёл специальный AdminID, добавил функцию вывода времени последнего изменения
parent bcd8ead4
......@@ -94,7 +94,7 @@ interface IOController_i : UniSetManager_i
CalibrateInfo getCalibrateInfo( in UniSetTypes::ObjectId sid ) raises(NameNotFound);
// --- Интерфес получения информации о всех датчиках ---
/*! Информация об аналоговом датчике */
/*! Информация датчике */
struct SensorIOInfo
{
long value; /*!< значение */
......@@ -108,6 +108,7 @@ interface IOController_i : UniSetManager_i
CalibrateInfo ci; /*!< калибровочные параметры */
long tv_sec; /*!< время последнего изменения датчика, секунды (gettimeofday) */
long tv_usec; /*!< время последнего изменения датчика, мксек (gettimeofday) */
UniSetTypes::ObjectId supplier; /*!< идентификатор объекта изменившего состояние датчика */
boolean dbignore; /*!< не сохранять изменения в БД */
};
......@@ -138,12 +139,13 @@ interface IOController_i : UniSetManager_i
UniSetTypes::IDSeq setOutputSeq( in OutSeq lst, in UniSetTypes::ObjectId sup_id );
/*! Информация о дискретном датчике */
/*! Информация о датчике */
struct ShortIOInfo
{
long value;
long tv_sec; /*!< время последнего изменения датчика, секунды (gettimeofday) */
long tv_usec; /*!< время последнего изменения датчика, мксек (gettimeofday) */
UniSetTypes::ObjectId supplier; /*!< идентификатор того, кто менял датчик (последний раз) */
};
ShortIOInfo getChangedTime( in UniSetTypes::ObjectId sid ) raises(NameNotFound);
......
......@@ -47,6 +47,12 @@ SQL:
- добавить работу с History (при передаче указателя на SM в конструкторе).
Debug:
- в codegen встроить получение состояния всех переменных (dumpIO() + UniSetObject::getInfo())
- (smonit): выводить того кто поменял датчик..
Version 2.5
============
- smonit запись значений в файл (csv?,sqlite?)
......
......@@ -49,6 +49,7 @@ static struct option longopts[] =
{ "getValue", required_argument, 0, 'g' },
{ "getRawValue", required_argument, 0, 'w' },
{ "getCalibrate", required_argument, 0, 'y' },
{ "getChangedTime", required_argument, 0, 't' },
{ "oinfo", required_argument, 0, 'p' },
{ "verbose", no_argument, 0, 'v' },
{ "quiet", no_argument, 0, 'q' },
......@@ -67,6 +68,7 @@ int logRotate( const string& args, UInterface& ui );
int setValue( const string& args, UInterface& ui );
int getValue( const string& args, UInterface& ui );
int getRawValue( const string& args, UInterface& ui );
int getChangedTime( const string& args, UInterface& ui );
int getState( const string& args, UInterface& ui );
int getCalibrate( const string& args, UInterface& ui );
int oinfo( const string& args, UInterface& ui );
......@@ -111,6 +113,7 @@ static void usage()
cout << endl;
print_help(36, "-w|--getRawValue id1@node1=val,id2@node2=val2,id3=val3,.. ", "Получить 'сырое' значение.\n");
print_help(36, "-y|--getCalibrate id1@node1=val,id2@node2=val2,id3=val3,.. ", "Получить параметры калибровки.\n");
print_help(36, "-t|--getChangedTime id1@node1=val,id2@node2=val2,id3=val3,.. ", "Получить время последнего изменения.\n");
print_help(36, "-v|--verbose", "Подробный вывод логов.\n");
print_help(36, "-q|--quiet", "Выводит только результат.\n");
cout << endl;
......@@ -174,6 +177,7 @@ int main(int argc, char** argv)
{
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return setValue(optarg, ui);
}
break;
......@@ -183,6 +187,7 @@ int main(int argc, char** argv)
// cout<<"(main):received option --getValue='"<<optarg<<"'"<<endl;
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return getValue(optarg, ui);
}
break;
......@@ -192,15 +197,26 @@ int main(int argc, char** argv)
// cout<<"(main):received option --getRawValue='"<<optarg<<"'"<<endl;
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return getRawValue(optarg, ui);
}
break;
case 't': //--getChangedTime
{
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return getChangedTime(optarg, ui);
}
break;
case 'p': //--oinfo
{
// cout<<"(main):received option --oinfo='"<<optarg<<"'"<<endl;
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return oinfo(optarg, ui);
}
break;
......@@ -210,6 +226,7 @@ int main(int argc, char** argv)
// cout<<"(main):received option --exist"<<endl;
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
verb = true;
Command cmd = Exist;
......@@ -226,6 +243,7 @@ int main(int argc, char** argv)
// cout<<"(main):received option --start"<<endl;
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
Command cmd = StartUp;
auto rep = make_shared<ObjectRepository>(conf);
......@@ -240,6 +258,7 @@ int main(int argc, char** argv)
{
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return configure(optarg, ui);
}
break;
......@@ -249,6 +268,7 @@ int main(int argc, char** argv)
// cout<<"(main):received option --finish"<<endl;
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
Command cmd = Finish;
auto rep = make_shared<ObjectRepository>(conf);
......@@ -266,6 +286,7 @@ int main(int argc, char** argv)
{
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return logRotate(optarg, ui);
}
break;
......@@ -275,6 +296,7 @@ int main(int argc, char** argv)
// cout<<"(main):received option --getCalibrate='"<<optarg<<"'"<<endl;
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return getCalibrate(optarg, ui);
}
break;
......@@ -284,6 +306,7 @@ int main(int argc, char** argv)
// cout<<"(main):received option --foldUp"<<endl;
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
Command cmd = FoldUp;
auto rep = make_shared<ObjectRepository>(conf);
......@@ -708,6 +731,44 @@ int getRawValue( const std::string& args, UInterface& ui )
}
// --------------------------------------------------------------------------------------
int getChangedTime( const std::string& args, UInterface& ui )
{
int err = 0;
auto conf = ui.getConf();
auto sl = UniSetTypes::getSInfoList( args, conf );
if( !quiet )
cout << "====== getChangedTime ======" << endl;
for( auto && it : sl )
{
if( it.si.node == DefaultObjectId )
it.si.node = conf->getLocalNode();
try
{
if( !quiet )
{
cout << " name: (" << it.si.id << ") " << it.fname << endl;
cout << " text: " << conf->oind->getTextName(it.si.id) << "\n\n";
cout << ui.getChangedTime(it.si.id,it.si.node) << endl;
}
else
cout << ui.getChangedTime(it.si.id,it.si.node);
}
catch( const Exception& ex )
{
if( !quiet )
cerr << "(getChangedTime): " << ex << endl;;
err = 1;
}
}
return err;
}
// --------------------------------------------------------------------------------------
int logRotate( const string& arg, UInterface& ui )
{
auto conf = ui.getConf();
......
......@@ -12,6 +12,7 @@ ln -s -f admin.sh msgmap
ln -s -f admin.sh setValue
ln -s -f admin.sh getValue
ln -s -f admin.sh getRawValue
ln -s -f admin.sh getChangedTime
ln -s -f admin.sh getCalibrate
ln -s -f admin.sh help
ln -s -f admin.sh oinfo
......
......@@ -6,7 +6,7 @@ smemory_test_LDADD = $(top_builddir)/lib/libUniSet2.la \
smemory_test_CPPFLAGS = -I$(top_builddir)/include \
-I$(top_builddir)/extensions/include \
-I$(top_builddir)/extensions/SharedMemory \
$(SIGC_CFLAGS) $(COMCPP_CFLAGS)
$(SIGC_CFLAGS) $(COMCPP_CFLAGS)
smemory_test_SOURCES = TestProc_SK.cc TestProc.cc smemory-test.cc
TestProc_SK.cc: testproc.src.xml
......
......@@ -106,7 +106,7 @@ void TestProc::timerInfo( const TimerMessage* tm )
cerr << "LOGLEVEL: [" << (int)(*lit) << "] " << (*lit) << endl;
for( auto& it : loglevels )
mylog[it] << myname << ": test log print..." << endl;
mylog->debug(it) << myname << ": test log print..." << endl;
cerr << "======= END LOG PRINT ======" << endl;
}
......@@ -138,7 +138,7 @@ void TestProc::test_undefined_state()
undef ^= true;
si.id = undef_c;
si.node = conf->getLocalNode();
si.node = uniset_conf()->getLocalNode();
cerr << myname << ": set undefined=" << undef << endl;
ui->setUndefinedState( si, undef, getId() );
}
......
......@@ -10,7 +10,7 @@ class TestProc:
public TestProc_SK
{
public:
TestProc( UniSetTypes::ObjectId id, xmlNode* confnode = UniSetTypes::conf->getNode("TestProc") );
TestProc( UniSetTypes::ObjectId id, xmlNode* confnode = UniSetTypes::uniset_conf()->getNode("TestProc") );
virtual ~TestProc();
protected:
......
......@@ -20,13 +20,7 @@ int main(int argc, const char** argv)
try
{
string confile = UniSetTypes::getArgParam( "--confile", argc, argv, "configure.xml" );
conf = new Configuration(argc, argv, confile);
string logfilename = conf->getArgParam("--logfile", "smemory.log");
string logname( conf->getLogDir() + logfilename );
ulog()->logFile( logname );
dlog()->logFile( logname );
auto conf = uniset_init(argc, argv);
auto shm = SharedMemory::init_smemory(argc, argv);
......@@ -45,9 +39,9 @@ int main(int argc, const char** argv)
s << "TestProc" << i;
cout << "..create " << s.str() << endl;
TestProc* tp = new TestProc(conf->getObjectID(s.str()));
tp->init_dlog(dlog);
act->add(tp->get_ptr());
auto tp = make_shared<TestProc>( conf->getObjectID(s.str()));
// tp->init_dlog(dlog());
act->add(tp);
}
SystemMessage sm(SystemMessage::StartUp);
......
......@@ -192,7 +192,8 @@ class IOController:
inline IOController_i::SensorIOInfo
SensorIOInfo(long v, UniversalIO::IOType t, const IOController_i::SensorInfo& si,
UniSetTypes::Message::Priority p = UniSetTypes::Message::Medium,
long defval = 0, IOController_i::CalibrateInfo* ci = 0 )
long defval = 0, IOController_i::CalibrateInfo* ci = 0,
UniSetTypes::ObjectId sup_id = UniSetTypes::DefaultObjectId )
{
IOController_i::SensorIOInfo ai;
ai.si = si;
......@@ -202,6 +203,7 @@ class IOController:
ai.default_val = defval;
ai.real_value = v;
ai.blocked = false;
ai.supplier = sup_id;
if( ci != 0 )
ai.ci = *ci;
......@@ -295,6 +297,7 @@ class IOController:
dbignore = false;
undefined = false;
blocked = false;
supplier = UniSetTypes::DefaultObjectId;
}
virtual ~USensorInfo() {}
......@@ -332,19 +335,20 @@ class IOController:
void init( const IOController_i::SensorIOInfo& s );
inline IOController_i::SensorIOInfo getSIO()
inline IOController_i::SensorIOInfo makeSensorIOInfo()
{
UniSetTypes::uniset_rwmutex_rlock lock(val_lock);
IOController_i::SensorIOInfo s(*this);
return std::move(s);
}
inline UniSetTypes::SensorMessage getSM()
inline UniSetTypes::SensorMessage makeSensorMessage()
{
UniSetTypes::uniset_rwmutex_rlock lock(val_lock);
UniSetTypes::SensorMessage sm;
UniSetTypes::uniset_rwmutex_rlock lock(val_lock);
sm.id = si.id;
sm.node = si.node;
sm.node = si.node; // uniset_conf()->getLocalNode()?
sm.sensor_type = type;
sm.value = value;
sm.undefined = undefined;
......@@ -352,6 +356,7 @@ class IOController:
sm.sm_tv_sec = tv_sec;
sm.sm_tv_usec = tv_usec;
sm.ci = ci;
sm.supplier = supplier;
return std::move(sm);
}
};
......
......@@ -46,7 +46,7 @@ namespace UniSetTypes
TheLastFieldOfTypeOfMessage // Обязательно оставьте последним
};
int type; // Содержание сообщения (тип)
int type = { Unused }; // Содержание сообщения (тип)
enum Priority
{
......@@ -56,10 +56,10 @@ namespace UniSetTypes
Super
};
Priority priority;
ObjectId node; // откуда
ObjectId supplier; // от кого
ObjectId consumer; // кому
Priority priority = { Medium };
ObjectId node = { UniSetTypes::DefaultObjectId }; // откуда
ObjectId supplier = { UniSetTypes::DefaultObjectId }; // от кого
ObjectId consumer = { UniSetTypes::DefaultObjectId }; // кому
struct timeval tm;
......
......@@ -58,6 +58,8 @@ namespace UniSetTypes
const ThresholdId DefaultThresholdId = -1; /*!< идентификатор порогов по умолчанию */
const ThresholdId DefaultTimerId = -1; /*!< идентификатор таймера по умолчанию */
const ObjectId AdminID = -2; /*!< сервисный идентификатор используемый утилитой admin */
typedef unsigned long KeyType; /*!< уникальный ключ объекта */
/*! генератор уникального положительного ключа
......@@ -87,6 +89,7 @@ namespace UniSetTypes
UniversalIO::IOType getIOType( const std::string& s );
std::ostream& operator<<( std::ostream& os, const UniversalIO::IOType t );
std::ostream& operator<<( std::ostream& os, const IONotifyController_i::ThresholdInfo& ti );
std::ostream& operator<<( std::ostream& os, const IOController_i::ShortIOInfo& s );
/*! Команды для управления лампочками */
enum LampCommand
......
......@@ -458,3 +458,11 @@ std::ostream& UniSetTypes::operator<<( std::ostream& os, const IONotifyControlle
return os;
}
// -------------------------------------------------------------------------
std::ostream& UniSetTypes::operator<<( std::ostream& os, const IOController_i::ShortIOInfo& s )
{
os << setw(10) << dateToString(s.tv_sec)
<< " " << setw(8) << timeToString(s.tv_sec) << "." << s.tv_usec
<< " [ value=" << s.value << " supplier=" << s.supplier << " ]";
return os;
}
......@@ -286,10 +286,13 @@ void IOController::localSetValue( std::shared_ptr<USensorInfo>& usi,
// lock
uniset_rwmutex_wrlock lock(usi->val_lock);
usi->supplier = sup_id; // запоминаем того кто изменил
// фильтрам может потребоваться измениять исходное значение (например для усреднения)
// поэтому передаём (и затем сохраняем) напрямую(ссылку) value (а не const value)
bool blocked = ( usi->blocked || usi->undefined );
if( checkIOFilters(usi, value, sup_id) || blocked )
{
uinfo << myname << ": save sensor value (" << sid << ")"
......@@ -393,6 +396,7 @@ void IOController::ioRegistration( std::shared_ptr<USensorInfo>& ainf, bool forc
ai->tv_sec = tm.tv_sec;
ai->tv_usec = tm.tv_usec;
ai->value = ai->default_val;
ai->supplier = getId();
// более оптимальный способ(при условии вставки первый раз)
ioList.emplace( IOStateList::value_type(ainf->si.id, std::move(ai) ));
......@@ -471,7 +475,7 @@ void IOController::dumpToDB()
{
if ( !li->second->dbignore )
{
SensorMessage sm(li->second->getSM());
SensorMessage sm(li->second->makeSensorMessage());
logging(sm);
}
}
......@@ -692,7 +696,7 @@ IOController_i::SensorInfoSeq* IOController::getSensorSeq( const IDSeq& lst )
if( it != ioList.end() )
{
(*res)[i] = it->second->getSIO();
(*res)[i] = it->second->makeSensorIOInfo();
continue;
}
......@@ -739,10 +743,12 @@ IOController_i::ShortIOInfo IOController::getChangedTime( UniSetTypes::ObjectId
if( ait != ioList.end() )
{
IOController_i::ShortIOInfo i;
uniset_rwmutex_rlock lock(ait->second->val_lock);
i.value = ait->second->value;
i.tv_sec = ait->second->tv_sec;
i.tv_usec = ait->second->tv_usec;
auto s = ait->second;
uniset_rwmutex_rlock lock(s->val_lock);
i.value = s->value;
i.tv_sec = s->tv_sec;
i.tv_usec = s->tv_usec;
i.supplier = s->supplier;
return i;
}
......@@ -829,15 +835,17 @@ IOController::ChangeUndefinedStateSignal IOController::signal_change_undefined_s
void IOController::USensorInfo::checkDepend( std::shared_ptr<USensorInfo>& d_it, IOController* ic )
{
bool changed = false;
ObjectId sup_id = ic->getId();
{
uniset_rwmutex_wrlock lock(val_lock);
bool prev = blocked;
uniset_rwmutex_rlock dlock(d_it->val_lock);
blocked = ( d_it->value == d_value ) ? false : true;
changed = ( prev != blocked );
sup_id = d_it->supplier;
}
if( changed )
ic->localSetValue( it, si.id, real_value, ic->getId() );
ic->localSetValue( it, si.id, real_value, sup_id );
}
// -----------------------------------------------------------------------------
......@@ -159,24 +159,7 @@ void IONotifyController::askSensor(const UniSetTypes::ObjectId sid,
// посылка первый раз состояния
if( cmd == UniversalIO::UIONotify || (cmd == UIONotifyFirstNotNull && li->second->value) )
{
SensorMessage smsg;
smsg.id = sid;
smsg.node = uniset_conf()->getLocalNode();
smsg.consumer = ci.id;
smsg.supplier = getId();
smsg.sensor_type = li->second->type;
smsg.priority = (Message::Priority)li->second->priority;
smsg.sm_tv_sec = li->second->tv_sec;
smsg.sm_tv_usec = li->second->tv_usec;
smsg.ci = li->second->ci;
{
uniset_rwmutex_rlock lock(li->second->val_lock);
smsg.value = li->second->value;
smsg.undefined = li->second->undefined;
smsg.sm_tv_sec = li->second->tv_sec;
smsg.sm_tv_usec = li->second->tv_usec;
}
SensorMessage smsg(li->second->makeSensorMessage());
try
{
ui->send(ci.id, std::move(smsg.transport_msg()), ci.node);
......@@ -342,7 +325,7 @@ void IONotifyController::localSetValue( IOController::IOStateList::iterator& li,
sm.value = li->second->value;
sm.undefined = li->second->undefined;
sm.priority = (Message::Priority)li->second->priority;
sm.supplier = sup_id;
sm.supplier = sup_id; // owner_id
sm.sensor_type = li->second->type;
sm.sm_tv_sec = li->second->tv_sec;
sm.sm_tv_usec = li->second->tv_usec;
......@@ -724,19 +707,9 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li,
if( li == myioEnd() )
return; // ???
SensorMessage sm;
sm.id = sid;
sm.node = uniset_conf()->getLocalNode();
sm.sensor_type = li->second->type;
sm.priority = (Message::Priority)li->second->priority;
sm.ci = li->second->ci;
{
uniset_rwmutex_rlock lock(li->second->val_lock);
sm.value = li->second->value;
sm.undefined = li->second->undefined;
sm.sm_tv_sec = li->second->tv_sec;
sm.sm_tv_usec = li->second->tv_usec;
}
auto s = li->second;
SensorMessage sm(s->makeSensorMessage());
// текущее время
struct timeval tm;
......@@ -794,7 +767,7 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li,
{
try
{
localSetValue(it->sit, it->sid, (sm.threshold ? 1 : 0), getId());
localSetValue(it->sit, it->sid, (sm.threshold ? 1 : 0), s->supplier);
}
catch( UniSetTypes::Exception& ex )
{
......@@ -964,24 +937,7 @@ IONotifyController_i::ThresholdsListSeq* IONotifyController::getThresholdsList()
// -----------------------------------------------------------------------------
void IONotifyController::onChangeUndefinedState( std::shared_ptr<USensorInfo>& it, IOController* ic )
{
SensorMessage sm;
// эти поля можно копировать без lock, т.к. они не меняются
sm.id = it->si.id;
sm.node = it->si.node;
sm.undefined = it->undefined;
sm.priority = (Message::Priority)it->priority;
sm.sensor_type = it->type;
sm.supplier = DefaultObjectId;
{
// lock
uniset_rwmutex_rlock lock(it->val_lock);
sm.value = it->value;
sm.sm_tv_sec = it->tv_sec;
sm.sm_tv_usec = it->tv_usec;
sm.ci = it->ci;
} // unlock
SensorMessage sm( it->makeSensorMessage() );
try
{
......
......@@ -84,10 +84,23 @@ void SMonitor::sysCommand( const SystemMessage* sm )
// ------------------------------------------------------------------------------------------
void SMonitor::sensorInfo( const SensorMessage* si )
{
cout << "(" << setw(6) << si->id << "): " << setw(8) << timeToString(si->sm_tv_sec, ":")
<< "(" << setw(6) << si->sm_tv_usec << "): ";
cout << setw(45) << uniset_conf()->oind->getMapName(si->id);
cout << "\tvalue=" << si->value << "\tfvalue=" << ( (float)si->value / pow(10.0, si->ci.precision) ) << endl;
auto conf = uniset_conf();
string s_sup("");
if( si->supplier == UniSetTypes::AdminID )
s_sup = "uniset-admin";
else
s_sup = ORepHelpers::getShortName(conf->oind->getMapName(si->supplier));
cout << "(" << setw(6) << si->id << "):"
<< "[(" << std::right << setw(5) << si->supplier << ")"
<< std::left << setw(20) << s_sup << "] "
<< std::right << setw(8) << timeToString(si->sm_tv_sec, ":")
<< "(" << setw(6) << si->sm_tv_usec << "): "
<< std::right << setw(45) << conf->oind->getMapName(si->id)
<< " value:" << std::right << setw(9) << si->value
<< " fvalue:" << std::right << setw(12) << ( (float)si->value / pow(10.0, si->ci.precision) ) << endl;
if( !script.empty() )
{
......@@ -98,7 +111,7 @@ void SMonitor::sensorInfo( const SensorMessage* si )
if( script[0] == '.' || script[0] == '/' )
cmd << script;
else
cmd << uniset_conf()->getBinDir() << script;
cmd << conf->getBinDir() << script;
cmd << " " << si->id << " " << si->value << " " << si->sm_tv_sec << " " << si->sm_tv_usec;
......
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