Commit 618e6fba authored by Pavel Vainerman's avatar Pavel Vainerman

make style, fix docs

parent 1a629d75
......@@ -11,112 +11,112 @@
/*! Ничего не делающая реализация MBSlave для тестирования */
class MBSlave
{
public:
MBSlave( const std::unordered_set<uniset::ModbusRTU::ModbusAddr>& vaddr, const std::string& dev, const std::string& speed, bool use485 = false );
~MBSlave();
inline void setVerbose( bool state )
{
verbose = state;
}
inline void setReply( long val )
{
replyVal = val;
}
inline void setReply2( long val )
{
replyVal2 = val;
}
inline void setReply3( long val )
{
replyVal3 = val;
}
void execute(); /*!< основной цикл работы */
void setLog( std::shared_ptr<DebugStream> dlog );
protected:
// действия при завершении работы
void sigterm( int signo );
/*! обработка 0x01 */
uniset::ModbusRTU::mbErrCode readCoilStatus( uniset::ModbusRTU::ReadCoilMessage& query,
uniset::ModbusRTU::ReadCoilRetMessage& reply );
/*! обработка 0x02 */
uniset::ModbusRTU::mbErrCode readInputStatus( uniset::ModbusRTU::ReadInputStatusMessage& query,
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
/*! обработка 0x03 */
uniset::ModbusRTU::mbErrCode readOutputRegisters( uniset::ModbusRTU::ReadOutputMessage& query,
uniset::ModbusRTU::ReadOutputRetMessage& reply );
/*! обработка 0x04 */
uniset::ModbusRTU::mbErrCode readInputRegisters( uniset::ModbusRTU::ReadInputMessage& query,
uniset::ModbusRTU::ReadInputRetMessage& reply );
/*! обработка 0x05 */
uniset::ModbusRTU::mbErrCode forceSingleCoil( uniset::ModbusRTU::ForceSingleCoilMessage& query,
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
/*! обработка 0x0F */
uniset::ModbusRTU::mbErrCode forceMultipleCoils( uniset::ModbusRTU::ForceCoilsMessage& query,
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
/*! обработка 0x10 */
uniset::ModbusRTU::mbErrCode writeOutputRegisters( uniset::ModbusRTU::WriteOutputMessage& query,
uniset::ModbusRTU::WriteOutputRetMessage& reply );
/*! обработка 0x06 */
uniset::ModbusRTU::mbErrCode writeOutputSingleRegister( uniset::ModbusRTU::WriteSingleOutputMessage& query,
uniset::ModbusRTU::WriteSingleOutputRetMessage& reply );
/*! обработка запросов на чтение ошибок */
uniset::ModbusRTU::mbErrCode journalCommand( uniset::ModbusRTU::JournalCommandMessage& query,
uniset::ModbusRTU::JournalCommandRetMessage& reply );
/*! обработка запроса на установку времени */
uniset::ModbusRTU::mbErrCode setDateTime( uniset::ModbusRTU::SetDateTimeMessage& query,
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
/*! обработка запроса удалённого сервиса */
uniset::ModbusRTU::mbErrCode remoteService( uniset::ModbusRTU::RemoteServiceMessage& query,
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
uniset::ModbusRTU::mbErrCode fileTransfer( uniset::ModbusRTU::FileTransferMessage& query,
uniset::ModbusRTU::FileTransferRetMessage& reply );
uniset::ModbusRTU::mbErrCode diagnostics( uniset::ModbusRTU::DiagnosticMessage& query,
uniset::ModbusRTU::DiagnosticRetMessage& reply );
uniset::ModbusRTU::mbErrCode read4314( uniset::ModbusRTU::MEIMessageRDI& query,
uniset::ModbusRTU::MEIMessageRetRDI& reply );
/*! интерфейс ModbusRTUSlave для обмена по RS */
uniset::ModbusRTUSlaveSlot* rscomm;
std::unordered_set<uniset::ModbusRTU::ModbusAddr> vaddr; /*!< адреса на которые отвечаем */
bool verbose;
public:
MBSlave( const std::unordered_set<uniset::ModbusRTU::ModbusAddr>& vaddr, const std::string& dev, const std::string& speed, bool use485 = false );
~MBSlave();
inline void setVerbose( bool state )
{
verbose = state;
}
inline void setReply( long val )
{
replyVal = val;
}
inline void setReply2( long val )
{
replyVal2 = val;
}
inline void setReply3( long val )
{
replyVal3 = val;
}
void execute(); /*!< основной цикл работы */
void setLog( std::shared_ptr<DebugStream> dlog );
protected:
// действия при завершении работы
void sigterm( int signo );
/*! обработка 0x01 */
uniset::ModbusRTU::mbErrCode readCoilStatus( uniset::ModbusRTU::ReadCoilMessage& query,
uniset::ModbusRTU::ReadCoilRetMessage& reply );
/*! обработка 0x02 */
uniset::ModbusRTU::mbErrCode readInputStatus( uniset::ModbusRTU::ReadInputStatusMessage& query,
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
/*! обработка 0x03 */
uniset::ModbusRTU::mbErrCode readOutputRegisters( uniset::ModbusRTU::ReadOutputMessage& query,
uniset::ModbusRTU::ReadOutputRetMessage& reply );
/*! обработка 0x04 */
uniset::ModbusRTU::mbErrCode readInputRegisters( uniset::ModbusRTU::ReadInputMessage& query,
uniset::ModbusRTU::ReadInputRetMessage& reply );
/*! обработка 0x05 */
uniset::ModbusRTU::mbErrCode forceSingleCoil( uniset::ModbusRTU::ForceSingleCoilMessage& query,
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
/*! обработка 0x0F */
uniset::ModbusRTU::mbErrCode forceMultipleCoils( uniset::ModbusRTU::ForceCoilsMessage& query,
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
/*! обработка 0x10 */
uniset::ModbusRTU::mbErrCode writeOutputRegisters( uniset::ModbusRTU::WriteOutputMessage& query,
uniset::ModbusRTU::WriteOutputRetMessage& reply );
/*! обработка 0x06 */
uniset::ModbusRTU::mbErrCode writeOutputSingleRegister( uniset::ModbusRTU::WriteSingleOutputMessage& query,
uniset::ModbusRTU::WriteSingleOutputRetMessage& reply );
/*! обработка запросов на чтение ошибок */
uniset::ModbusRTU::mbErrCode journalCommand( uniset::ModbusRTU::JournalCommandMessage& query,
uniset::ModbusRTU::JournalCommandRetMessage& reply );
/*! обработка запроса на установку времени */
uniset::ModbusRTU::mbErrCode setDateTime( uniset::ModbusRTU::SetDateTimeMessage& query,
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
/*! обработка запроса удалённого сервиса */
uniset::ModbusRTU::mbErrCode remoteService( uniset::ModbusRTU::RemoteServiceMessage& query,
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
uniset::ModbusRTU::mbErrCode fileTransfer( uniset::ModbusRTU::FileTransferMessage& query,
uniset::ModbusRTU::FileTransferRetMessage& reply );
uniset::ModbusRTU::mbErrCode diagnostics( uniset::ModbusRTU::DiagnosticMessage& query,
uniset::ModbusRTU::DiagnosticRetMessage& reply );
uniset::ModbusRTU::mbErrCode read4314( uniset::ModbusRTU::MEIMessageRDI& query,
uniset::ModbusRTU::MEIMessageRetRDI& reply );
/*! интерфейс ModbusRTUSlave для обмена по RS */
uniset::ModbusRTUSlaveSlot* rscomm;
std::unordered_set<uniset::ModbusRTU::ModbusAddr> vaddr; /*!< адреса на которые отвечаем */
bool verbose;
#if 0
typedef std::unordered_map<uniset::ModbusRTU::mbErrCode, unsigned int> ExchangeErrorMap;
ExchangeErrorMap errmap; /*!< статистика обмена */
uniset::ModbusRTU::mbErrCode prev;
typedef std::unordered_map<uniset::ModbusRTU::mbErrCode, unsigned int> ExchangeErrorMap;
ExchangeErrorMap errmap; /*!< статистика обмена */
uniset::ModbusRTU::mbErrCode prev;
// можно было бы сделать unsigned, но аналоговые датчики у нас имеют
// тип long. А это число передаётся в графику в виде аналогового датчика
long askCount; /*!< количество принятых запросов */
// можно было бы сделать unsigned, но аналоговые датчики у нас имеют
// тип long. А это число передаётся в графику в виде аналогового датчика
long askCount; /*!< количество принятых запросов */
typedef std::unordered_map<int, std::string> FileList;
FileList flist;
typedef std::unordered_map<int, std::string> FileList;
FileList flist;
#endif
long replyVal;
long replyVal2;
long replyVal3;
private:
long replyVal;
long replyVal2;
long replyVal3;
private:
};
// -------------------------------------------------------------------------
......
......@@ -9,111 +9,111 @@
/*! Ничего не делающая реализация MBTCPServer для тестирования */
class MBTCPServer
{
public:
MBTCPServer( const std::unordered_set<uniset::ModbusRTU::ModbusAddr>& myaddr, const std::string& inetaddr, int port = 502, bool verbose = false );
~MBTCPServer();
public:
MBTCPServer( const std::unordered_set<uniset::ModbusRTU::ModbusAddr>& myaddr, const std::string& inetaddr, int port = 502, bool verbose = false );
~MBTCPServer();
inline void setVerbose( bool state )
{
verbose = state;
}
inline void setVerbose( bool state )
{
verbose = state;
}
inline void setReply( long val )
{
replyVal = val;
}
inline void setReply( long val )
{
replyVal = val;
}
inline uniset::timeout_t setAfterSendPause( uniset::timeout_t msec )
{
return sslot->setAfterSendPause(msec);
}
inline uniset::timeout_t setAfterSendPause( uniset::timeout_t msec )
{
return sslot->setAfterSendPause(msec);
}
void execute(); /*!< основной цикл работы */
void setLog( std::shared_ptr<DebugStream>& dlog );
void execute(); /*!< основной цикл работы */
void setLog( std::shared_ptr<DebugStream>& dlog );
void setMaxSessions( size_t max );
void setMaxSessions( size_t max );
protected:
// действия при завершении работы
void sigterm( int signo );
protected:
// действия при завершении работы
void sigterm( int signo );
/*! обработка 0x01 */
uniset::ModbusRTU::mbErrCode readCoilStatus( uniset::ModbusRTU::ReadCoilMessage& query,
uniset::ModbusRTU::ReadCoilRetMessage& reply );
/*! обработка 0x02 */
uniset::ModbusRTU::mbErrCode readInputStatus( uniset::ModbusRTU::ReadInputStatusMessage& query,
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
/*! обработка 0x01 */
uniset::ModbusRTU::mbErrCode readCoilStatus( uniset::ModbusRTU::ReadCoilMessage& query,
uniset::ModbusRTU::ReadCoilRetMessage& reply );
/*! обработка 0x02 */
uniset::ModbusRTU::mbErrCode readInputStatus( uniset::ModbusRTU::ReadInputStatusMessage& query,
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
/*! обработка 0x03 */
uniset::ModbusRTU::mbErrCode readOutputRegisters( uniset::ModbusRTU::ReadOutputMessage& query,
uniset::ModbusRTU::ReadOutputRetMessage& reply );
/*! обработка 0x03 */
uniset::ModbusRTU::mbErrCode readOutputRegisters( uniset::ModbusRTU::ReadOutputMessage& query,
uniset::ModbusRTU::ReadOutputRetMessage& reply );
/*! обработка 0x04 */
uniset::ModbusRTU::mbErrCode readInputRegisters( uniset::ModbusRTU::ReadInputMessage& query,
uniset::ModbusRTU::ReadInputRetMessage& reply );
/*! обработка 0x04 */
uniset::ModbusRTU::mbErrCode readInputRegisters( uniset::ModbusRTU::ReadInputMessage& query,
uniset::ModbusRTU::ReadInputRetMessage& reply );
/*! обработка 0x05 */
uniset::ModbusRTU::mbErrCode forceSingleCoil( uniset::ModbusRTU::ForceSingleCoilMessage& query,
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
/*! обработка 0x05 */
uniset::ModbusRTU::mbErrCode forceSingleCoil( uniset::ModbusRTU::ForceSingleCoilMessage& query,
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
/*! обработка 0x0F */
uniset::ModbusRTU::mbErrCode forceMultipleCoils( uniset::ModbusRTU::ForceCoilsMessage& query,
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
/*! обработка 0x0F */
uniset::ModbusRTU::mbErrCode forceMultipleCoils( uniset::ModbusRTU::ForceCoilsMessage& query,
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
/*! обработка 0x10 */
uniset::ModbusRTU::mbErrCode writeOutputRegisters( uniset::ModbusRTU::WriteOutputMessage& query,
uniset::ModbusRTU::WriteOutputRetMessage& reply );
/*! обработка 0x10 */
uniset::ModbusRTU::mbErrCode writeOutputRegisters( uniset::ModbusRTU::WriteOutputMessage& query,
uniset::ModbusRTU::WriteOutputRetMessage& reply );
/*! обработка 0x06 */
uniset::ModbusRTU::mbErrCode writeOutputSingleRegister( uniset::ModbusRTU::WriteSingleOutputMessage& query,
uniset::ModbusRTU::WriteSingleOutputRetMessage& reply );
/*! обработка 0x06 */
uniset::ModbusRTU::mbErrCode writeOutputSingleRegister( uniset::ModbusRTU::WriteSingleOutputMessage& query,
uniset::ModbusRTU::WriteSingleOutputRetMessage& reply );
uniset::ModbusRTU::mbErrCode diagnostics( uniset::ModbusRTU::DiagnosticMessage& query,
uniset::ModbusRTU::DiagnosticRetMessage& reply );
uniset::ModbusRTU::mbErrCode diagnostics( uniset::ModbusRTU::DiagnosticMessage& query,
uniset::ModbusRTU::DiagnosticRetMessage& reply );
uniset::ModbusRTU::mbErrCode read4314( uniset::ModbusRTU::MEIMessageRDI& query,
uniset::ModbusRTU::MEIMessageRetRDI& reply );
uniset::ModbusRTU::mbErrCode read4314( uniset::ModbusRTU::MEIMessageRDI& query,
uniset::ModbusRTU::MEIMessageRetRDI& reply );
/*! обработка запросов на чтение ошибок */
uniset::ModbusRTU::mbErrCode journalCommand( uniset::ModbusRTU::JournalCommandMessage& query,
uniset::ModbusRTU::JournalCommandRetMessage& reply );
/*! обработка запросов на чтение ошибок */
uniset::ModbusRTU::mbErrCode journalCommand( uniset::ModbusRTU::JournalCommandMessage& query,
uniset::ModbusRTU::JournalCommandRetMessage& reply );
/*! обработка запроса на установку времени */
uniset::ModbusRTU::mbErrCode setDateTime( uniset::ModbusRTU::SetDateTimeMessage& query,
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
/*! обработка запроса на установку времени */
uniset::ModbusRTU::mbErrCode setDateTime( uniset::ModbusRTU::SetDateTimeMessage& query,
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
/*! обработка запроса удалённого сервиса */
uniset::ModbusRTU::mbErrCode remoteService( uniset::ModbusRTU::RemoteServiceMessage& query,
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
/*! обработка запроса удалённого сервиса */
uniset::ModbusRTU::mbErrCode remoteService( uniset::ModbusRTU::RemoteServiceMessage& query,
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
uniset::ModbusRTU::mbErrCode fileTransfer( uniset::ModbusRTU::FileTransferMessage& query,
uniset::ModbusRTU::FileTransferRetMessage& reply );
uniset::ModbusRTU::mbErrCode fileTransfer( uniset::ModbusRTU::FileTransferMessage& query,
uniset::ModbusRTU::FileTransferRetMessage& reply );
/*! интерфейс ModbusSlave для обмена по RS */
uniset::ModbusTCPServerSlot* sslot;
std::unordered_set<uniset::ModbusRTU::ModbusAddr> vaddr; /*!< адреса данного узла */
/*! интерфейс ModbusSlave для обмена по RS */
uniset::ModbusTCPServerSlot* sslot;
std::unordered_set<uniset::ModbusRTU::ModbusAddr> vaddr; /*!< адреса данного узла */
bool verbose = { false };
long replyVal = { -1 };
bool verbose = { false };
long replyVal = { -1 };
#if 0
typedef std::unordered_map<uniset::ModbusRTU::mbErrCode, unsigned int> ExchangeErrorMap;
ExchangeErrorMap errmap; /*!< статистика обмена */
uniset::ModbusRTU::mbErrCode prev;
typedef std::unordered_map<uniset::ModbusRTU::mbErrCode, unsigned int> ExchangeErrorMap;
ExchangeErrorMap errmap; /*!< статистика обмена */
uniset::ModbusRTU::mbErrCode prev;
// можно было бы сделать unsigned, но аналоговые датчики у нас имеют
// тип long. А это число передаётся в графику в виде аналогового датчика
long askCount; /*!< количество принятых запросов */
// можно было бы сделать unsigned, но аналоговые датчики у нас имеют
// тип long. А это число передаётся в графику в виде аналогового датчика
long askCount; /*!< количество принятых запросов */
typedef std::unordered_map<int, std::string> FileList;
FileList flist;
typedef std::unordered_map<int, std::string> FileList;
FileList flist;
#endif
private:
private:
};
// -------------------------------------------------------------------------
......
......@@ -10,147 +10,147 @@ using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] =
{
{ "help", no_argument, 0, 'h' },
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "myaddr", required_argument, 0, 'a' },
{ "speed", required_argument, 0, 's' },
{ "use485F", no_argument, 0, 'y' },
{ "const-reply", required_argument, 0, 'c' },
{ NULL, 0, 0, 0 }
{ "help", no_argument, 0, 'h' },
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "myaddr", required_argument, 0, 'a' },
{ "speed", required_argument, 0, 's' },
{ "use485F", no_argument, 0, 'y' },
{ "const-reply", required_argument, 0, 'c' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h|--help - this message\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-a|--myaddr] addr - Modbus address for master. Default: 0x01.\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-c|--const-reply] val1 [val2 val3] - Reply val for all queries\n");
printf("-h|--help - this message\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-a|--myaddr] addr - Modbus address for master. Default: 0x01.\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-c|--const-reply] val1 [val2 val3] - Reply val for all queries\n");
}
// --------------------------------------------------------------------------
static char* checkArg( int ind, int argc, char* argv[] );
// --------------------------------------------------------------------------
int main( int argc, char** argv )
{
// std::ios::sync_with_stdio(false);
int optindex = 0;
int opt = 0;
int verb = 0;
string dev("/dev/ttyS0");
string speed("38400");
ModbusRTU::ModbusAddr myaddr = 0x01;
auto dlog = make_shared<DebugStream>();
int use485 = 0;
int replyVal = -1;
int replyVal2 = -1;
int replyVal3 = -1;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hva:d:s:yc:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'd':
dev = string(optarg);
break;
case 's':
speed = string(optarg);
break;
case 'a':
myaddr = ModbusRTU::str2mbAddr(optarg);
break;
case 'v':
verb = 1;
break;
case 'y':
use485 = 1;
break;
case 'c':
replyVal = uni_atoi(optarg);
if( checkArg(optind, argc, argv) )
replyVal2 = uni_atoi(argv[optind]);
if( checkArg(optind + 1, argc, argv) )
replyVal3 = uni_atoi(argv[optind + 1]);
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
{
cout << "(init): dev=" << dev << " speed=" << speed
<< " myaddr=" << ModbusRTU::addr2str(myaddr)
<< endl;
dlog->addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
}
/*! \todo Доделать возможность задавать много адресов для ответа */
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
vaddr.emplace(myaddr);
MBSlave mbs(vaddr, dev, speed, use485);
mbs.setLog(dlog);
mbs.setVerbose(verb);
if( replyVal != -1 )
mbs.setReply(replyVal);
if( replyVal2 != -1 )
mbs.setReply2(replyVal2);
if( replyVal3 != -1 )
mbs.setReply3(replyVal3);
mbs.execute();
}
catch( ModbusRTU::mbException& ex )
{
cerr << "(mbtester): " << ex << endl;
}
catch( const std::exception& ex )
{
cerr << "(mbslave): " << ex.what() << endl;
}
catch(...)
{
cerr << "(mbslave): catch(...)" << endl;
}
return 0;
// std::ios::sync_with_stdio(false);
int optindex = 0;
int opt = 0;
int verb = 0;
string dev("/dev/ttyS0");
string speed("38400");
ModbusRTU::ModbusAddr myaddr = 0x01;
auto dlog = make_shared<DebugStream>();
int use485 = 0;
int replyVal = -1;
int replyVal2 = -1;
int replyVal3 = -1;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hva:d:s:yc:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'd':
dev = string(optarg);
break;
case 's':
speed = string(optarg);
break;
case 'a':
myaddr = ModbusRTU::str2mbAddr(optarg);
break;
case 'v':
verb = 1;
break;
case 'y':
use485 = 1;
break;
case 'c':
replyVal = uni_atoi(optarg);
if( checkArg(optind, argc, argv) )
replyVal2 = uni_atoi(argv[optind]);
if( checkArg(optind + 1, argc, argv) )
replyVal3 = uni_atoi(argv[optind + 1]);
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
{
cout << "(init): dev=" << dev << " speed=" << speed
<< " myaddr=" << ModbusRTU::addr2str(myaddr)
<< endl;
dlog->addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
}
/*! \todo Доделать возможность задавать много адресов для ответа */
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
vaddr.emplace(myaddr);
MBSlave mbs(vaddr, dev, speed, use485);
mbs.setLog(dlog);
mbs.setVerbose(verb);
if( replyVal != -1 )
mbs.setReply(replyVal);
if( replyVal2 != -1 )
mbs.setReply2(replyVal2);
if( replyVal3 != -1 )
mbs.setReply3(replyVal3);
mbs.execute();
}
catch( ModbusRTU::mbException& ex )
{
cerr << "(mbtester): " << ex << endl;
}
catch( const std::exception& ex )
{
cerr << "(mbslave): " << ex.what() << endl;
}
catch(...)
{
cerr << "(mbslave): catch(...)" << endl;
}
return 0;
}
// --------------------------------------------------------------------------
char* checkArg( int i, int argc, char* argv[] )
{
if( i < argc && (argv[i])[0] != '-' )
return argv[i];
if( i < argc && (argv[i])[0] != '-' )
return argv[i];
return 0;
return 0;
}
// --------------------------------------------------------------------------
......@@ -10,150 +10,150 @@ using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] =
{
{ "help", no_argument, 0, 'h' },
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "myaddr", required_argument, 0, 'a' },
{ "speed", required_argument, 0, 's' },
{ "f485", no_argument, 0, 'g' },
{ NULL, 0, 0, 0 }
{ "help", no_argument, 0, 'h' },
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "myaddr", required_argument, 0, 'a' },
{ "speed", required_argument, 0, 's' },
{ "f485", no_argument, 0, 'g' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h|--help - this message\n");
printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-a|--myaddr] addr1,addr2,... - Modbus address for this slave. Default: 0x01.\n");
printf(" myaddr=0 - Reply to all RTU-addresses (broadcast).\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-g|--f485] - Use 485 Fastwel\n");
printf("-h|--help - this message\n");
printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-a|--myaddr] addr1,addr2,... - Modbus address for this slave. Default: 0x01.\n");
printf(" myaddr=0 - Reply to all RTU-addresses (broadcast).\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-g|--f485] - Use 485 Fastwel\n");
}
// --------------------------------------------------------------------------
int main( int argc, char** argv )
{
// std::ios::sync_with_stdio(false);
int optindex = 0;
int opt = 0;
int verb = 0;
int f485 = 0;
string dev("/dev/ttyS0");
string speed("38400");
std::string myaddr("0x01");
int tout = 2000;
DebugStream dlog;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hva:d:s:c:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'd':
dev = string(optarg);
break;
case 's':
speed = string(optarg);
break;
case 't':
tout = uni_atoi(optarg);
break;
case 'a':
myaddr = string(optarg);
break;
case 'v':
verb = 1;
break;
case 'g':
f485 = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
auto avec = uniset::explode_str(myaddr, ',');
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
for( const auto& a : avec )
vaddr.emplace( ModbusRTU::str2mbAddr(a) );
if( verb )
{
cout << "(init): dev=" << dev << " speed=" << speed
<< " myaddr=" << ModbusServer::vaddr2str(vaddr)
<< " timeout=" << tout << " msec "
<< endl;
dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
}
if( f485 )
{
// std::ios::sync_with_stdio(false);
int optindex = 0;
int opt = 0;
int verb = 0;
int f485 = 0;
string dev("/dev/ttyS0");
string speed("38400");
std::string myaddr("0x01");
int tout = 2000;
DebugStream dlog;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hva:d:s:c:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'd':
dev = string(optarg);
break;
case 's':
speed = string(optarg);
break;
case 't':
tout = uni_atoi(optarg);
break;
case 'a':
myaddr = string(optarg);
break;
case 'v':
verb = 1;
break;
case 'g':
f485 = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
auto avec = uniset::explode_str(myaddr, ',');
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
for( const auto& a : avec )
vaddr.emplace( ModbusRTU::str2mbAddr(a) );
if( verb )
{
cout << "(init): dev=" << dev << " speed=" << speed
<< " myaddr=" << ModbusServer::vaddr2str(vaddr)
<< " timeout=" << tout << " msec "
<< endl;
dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
}
if( f485 )
{
#ifndef DISABLE_COMPORT_485F
ComPort485F* cp;
if( dev == "/dev/ttyS2" )
cp = new ComPort485F(dev, 5);
else if( dev == "/dev/ttyS3" )
cp = new ComPort485F(dev, 6);
else
{
cerr << "dev must be /dev/ttyS2 or /dev/tytS3" << endl;
return 1;
}
MBSlave mbs(cp, vaddr, speed);
mbs.setLog(dlog);
mbs.setVerbose(verb);
mbs.execute();
ComPort485F* cp;
if( dev == "/dev/ttyS2" )
cp = new ComPort485F(dev, 5);
else if( dev == "/dev/ttyS3" )
cp = new ComPort485F(dev, 6);
else
{
cerr << "dev must be /dev/ttyS2 or /dev/tytS3" << endl;
return 1;
}
MBSlave mbs(cp, vaddr, speed);
mbs.setLog(dlog);
mbs.setVerbose(verb);
mbs.execute();
#else
cerr << "DISABLE_COMPORT_485F" << endl;
return 1;
cerr << "DISABLE_COMPORT_485F" << endl;
return 1;
#endif // #ifndef DISABLE_COMPORT_485F
}
else
{
MBSlave mbs(vaddr, dev, speed);
mbs.setLog(dlog);
mbs.setVerbose(verb);
mbs.execute();
}
}
catch( const ModbusRTU::mbException& ex )
{
cerr << "(mbtester): " << ex << endl;
}
catch( const std::exception& ex )
{
cerr << "(mbslave): " << ex.what() << endl;
}
catch(...)
{
cerr << "(mbslave): catch(...)" << endl;
}
return 0;
}
else
{
MBSlave mbs(vaddr, dev, speed);
mbs.setLog(dlog);
mbs.setVerbose(verb);
mbs.execute();
}
}
catch( const ModbusRTU::mbException& ex )
{
cerr << "(mbtester): " << ex << endl;
}
catch( const std::exception& ex )
{
cerr << "(mbslave): " << ex.what() << endl;
}
catch(...)
{
cerr << "(mbslave): catch(...)" << endl;
}
return 0;
}
// --------------------------------------------------------------------------
......@@ -9,134 +9,134 @@ using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] =
{
{ "help", no_argument, 0, 'h' },
{ "iaddr", required_argument, 0, 'i' },
{ "verbose", no_argument, 0, 'v' },
{ "myaddr", required_argument, 0, 'a' },
{ "port", required_argument, 0, 'p' },
{ "const-reply", required_argument, 0, 'c' },
{ "after-send-pause", required_argument, 0, 's' },
{ "max-sessions", required_argument, 0, 'm' },
{ NULL, 0, 0, 0 }
{ "help", no_argument, 0, 'h' },
{ "iaddr", required_argument, 0, 'i' },
{ "verbose", no_argument, 0, 'v' },
{ "myaddr", required_argument, 0, 'a' },
{ "port", required_argument, 0, 'p' },
{ "const-reply", required_argument, 0, 'c' },
{ "after-send-pause", required_argument, 0, 's' },
{ "max-sessions", required_argument, 0, 'm' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("Example: uniset-mbtcpserver-echo -i localhost -p 2049 -v \n");
printf("-h|--help - this message\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-i|--iaddr] ip - Server listen ip. Default 127.0.0.1\n");
printf("[-a|--myaddr] addr1,addr2,... - Modbus address for master. Default: 0x01.\n");
printf(" myaddr=0 - Reply to all RTU-addresses (broadcast).\n");
printf("[-p|--port] port - Server port. Default: 502.\n");
printf("[-c|--const-reply] val - Reply 'val' for all queries\n");
printf("[-s|--after-send-pause] msec - Pause after send request. Default: 0\n");
printf("[-m|--max-sessions] num - Set the maximum number of sessions. Default: 10\n");
printf("Example: uniset-mbtcpserver-echo -i localhost -p 2049 -v \n");
printf("-h|--help - this message\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-i|--iaddr] ip - Server listen ip. Default 127.0.0.1\n");
printf("[-a|--myaddr] addr1,addr2,... - Modbus address for master. Default: 0x01.\n");
printf(" myaddr=0 - Reply to all RTU-addresses (broadcast).\n");
printf("[-p|--port] port - Server port. Default: 502.\n");
printf("[-c|--const-reply] val - Reply 'val' for all queries\n");
printf("[-s|--after-send-pause] msec - Pause after send request. Default: 0\n");
printf("[-m|--max-sessions] num - Set the maximum number of sessions. Default: 10\n");
}
// --------------------------------------------------------------------------
int main( int argc, char** argv )
{
// std::ios::sync_with_stdio(false);
int optindex = 0;
int opt = 0;
int verb = 0;
int port = 502;
string iaddr("127.0.0.1");
string myaddr("0x01");
auto dlog = make_shared<DebugStream>();
int replyVal = -1;
timeout_t afterpause = 0;
size_t maxSessions = 10;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hva:p:i:c:s:m:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'i':
iaddr = string(optarg);
break;
case 'p':
port = uni_atoi(optarg);
break;
case 'a':
myaddr = string(optarg);
break;
case 'v':
verb = 1;
break;
case 'c':
replyVal = uni_atoi(optarg);
break;
case 's':
afterpause = uni_atoi(optarg);
break;
case 'm':
maxSessions = uni_atoi(optarg);
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
auto avec = uniset::explode_str(myaddr, ',');
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
for( const auto& a : avec )
vaddr.emplace( ModbusRTU::str2mbAddr(a) );
if( verb )
{
cout << "(init): iaddr: " << iaddr << ":" << port
<< " myaddr=" << ModbusServer::vaddr2str(vaddr)
<< endl;
dlog->addLevel( Debug::ANY );
}
MBTCPServer mbs(vaddr, iaddr, port, verb);
mbs.setLog(dlog);
mbs.setVerbose(verb);
mbs.setAfterSendPause(afterpause);
mbs.setMaxSessions(maxSessions);
if( replyVal != -1 )
mbs.setReply(replyVal);
mbs.execute();
}
catch( const ModbusRTU::mbException& ex )
{
cerr << "(mbtcpserver): " << ex << endl;
}
catch( const std::exception& e )
{
cerr << "(mbtcpserver): " << e.what() << endl;
}
catch(...)
{
cerr << "(mbtcpserver): catch(...)" << endl;
}
return 0;
// std::ios::sync_with_stdio(false);
int optindex = 0;
int opt = 0;
int verb = 0;
int port = 502;
string iaddr("127.0.0.1");
string myaddr("0x01");
auto dlog = make_shared<DebugStream>();
int replyVal = -1;
timeout_t afterpause = 0;
size_t maxSessions = 10;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hva:p:i:c:s:m:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'i':
iaddr = string(optarg);
break;
case 'p':
port = uni_atoi(optarg);
break;
case 'a':
myaddr = string(optarg);
break;
case 'v':
verb = 1;
break;
case 'c':
replyVal = uni_atoi(optarg);
break;
case 's':
afterpause = uni_atoi(optarg);
break;
case 'm':
maxSessions = uni_atoi(optarg);
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
auto avec = uniset::explode_str(myaddr, ',');
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
for( const auto& a : avec )
vaddr.emplace( ModbusRTU::str2mbAddr(a) );
if( verb )
{
cout << "(init): iaddr: " << iaddr << ":" << port
<< " myaddr=" << ModbusServer::vaddr2str(vaddr)
<< endl;
dlog->addLevel( Debug::ANY );
}
MBTCPServer mbs(vaddr, iaddr, port, verb);
mbs.setLog(dlog);
mbs.setVerbose(verb);
mbs.setAfterSendPause(afterpause);
mbs.setMaxSessions(maxSessions);
if( replyVal != -1 )
mbs.setReply(replyVal);
mbs.execute();
}
catch( const ModbusRTU::mbException& ex )
{
cerr << "(mbtcpserver): " << ex << endl;
}
catch( const std::exception& e )
{
cerr << "(mbtcpserver): " << e.what() << endl;
}
catch(...)
{
cerr << "(mbtcpserver): catch(...)" << endl;
}
return 0;
}
// --------------------------------------------------------------------------
......@@ -8,28 +8,28 @@ using namespace std;
// --------------------------------------------------------------------------------
NullController::NullController( ObjectId id, const string& ioconfile,
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)
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)
{
restorer = NULL;
restorer = NULL;
auto ioconf = make_shared<IOConfig_XML>(ioconfile, uniset_conf());
ioconf->setItemFilter(s_filterField, s_filterValue);
ioconf->setConsumerFilter(c_filterField, c_filterValue);
auto ioconf = make_shared<IOConfig_XML>(ioconfile, uniset_conf());
ioconf->setItemFilter(s_filterField, s_filterValue);
ioconf->setConsumerFilter(c_filterField, c_filterValue);
restorer = std::static_pointer_cast<IOConfig>(ioconf);
restorer = std::static_pointer_cast<IOConfig>(ioconf);
/*
// askd->setReadItem( sigc::mem_fun(this,&NullController::readSItem) );
askd->setNCReadItem( sigc::mem_fun(this,&NullController::readSItem) );
askd->setReadThresholdItem( sigc::mem_fun(this,&NullController::readTItem) );
askd->setReadConsumerItem( sigc::mem_fun(this,&NullController::readCItem) );
*/
/*
// askd->setReadItem( sigc::mem_fun(this,&NullController::readSItem) );
askd->setNCReadItem( sigc::mem_fun(this,&NullController::readSItem) );
askd->setReadThresholdItem( sigc::mem_fun(this,&NullController::readTItem) );
askd->setReadConsumerItem( sigc::mem_fun(this,&NullController::readCItem) );
*/
}
// --------------------------------------------------------------------------------
......@@ -39,8 +39,8 @@ NullController::~NullController()
// --------------------------------------------------------------------------------
void NullController::dumpToDB()
{
if( dumpingToDB )
IONotifyController::dumpToDB();
if( dumpingToDB )
IONotifyController::dumpToDB();
}
// --------------------------------------------------------------------------------
/*
......
......@@ -6,28 +6,28 @@
#include "IONotifyController.h"
// --------------------------------------------------------------------------
class NullController:
public uniset::IONotifyController
public uniset::IONotifyController
{
public:
NullController(uniset::ObjectId id, const std::string& ioconfile,
const std::string& s_filterField = "",
const std::string& s_filterValue = "",
const std::string& c_filterField = "",
const std::string& c_filterValue = "",
bool _dumpingToDB = false );
public:
NullController(uniset::ObjectId id, const std::string& ioconfile,
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();
virtual ~NullController();
protected:
protected:
virtual void dumpToDB();
virtual void dumpToDB();
// bool readSItem( UniXML& xml, UniXML::iterator& it, xmlNode* sec, NCRestorer::SInfo& inf );
// bool readTItem( UniXML& xml, UniXML::iterator& it, xmlNode* sec);
// bool readCItem( UniXML& xml, UniXML::iterator& it, xmlNode* sec);
// bool readSItem( UniXML& xml, UniXML::iterator& it, xmlNode* sec, NCRestorer::SInfo& inf );
// bool readTItem( UniXML& xml, UniXML::iterator& it, xmlNode* sec);
// bool readCItem( UniXML& xml, UniXML::iterator& it, xmlNode* sec);
private:
bool dumpingToDB;
private:
bool dumpingToDB;
};
// --------------------------------------------------------------------------
......
......@@ -9,86 +9,86 @@ using namespace std;
// --------------------------------------------------------------------------
static void short_usage()
{
cout << "Usage: uniset-nullController"
<< "--confile configure.xml. По умолчанию: configure.xml." << endl
<< " --name ObjectId [--confile configure.xml] [--askfile filename] \n"
<< " --s-filter-field name - поле для фильтрования списка датчиков\n"
<< " --s-filter-value value - значение для поля фильтрования списка датчиков \n"
<< " --c-filter-field name - поле для фильтрования списка заказчиков по каждому датчику\n"
<< " --c-filter-value value - значение для поля фильтрования списка заказчиков по каждому датчику\n"
<< " --dbDumping [0,1] - создавать ли dump-файл \n";
cout << "Usage: uniset-nullController"
<< "--confile configure.xml. По умолчанию: configure.xml." << endl
<< " --name ObjectId [--confile configure.xml] [--askfile filename] \n"
<< " --s-filter-field name - поле для фильтрования списка датчиков\n"
<< " --s-filter-value value - значение для поля фильтрования списка датчиков \n"
<< " --c-filter-field name - поле для фильтрования списка заказчиков по каждому датчику\n"
<< " --c-filter-value value - значение для поля фильтрования списка заказчиков по каждому датчику\n"
<< " --dbDumping [0,1] - создавать ли dump-файл \n";
}
// --------------------------------------------------------------------------
int main(int argc, char** argv)
{
// std::ios::sync_with_stdio(false);
// std::ios::sync_with_stdio(false);
try
{
if( argc <= 1 )
{
cerr << "\nНе указаны необходимые параметры\n\n";
short_usage();
return 0;
}
try
{
if( argc <= 1 )
{
cerr << "\nНе указаны необходимые параметры\n\n";
short_usage();
return 0;
}
if( !strcmp(argv[1], "--help") )
{
short_usage();
return 0;
}
if( !strcmp(argv[1], "--help") )
{
short_usage();
return 0;
}
auto conf = uniset_init(argc, argv, "configure.xml");
auto conf = uniset_init(argc, argv, "configure.xml");
// определяем ID объекта
string name = conf->getArgParam("--name");
// определяем ID объекта
string name = conf->getArgParam("--name");
if( name.empty())
{
cerr << "(nullController): не задан ObjectId!!! (--name)\n";
return 0;
}
if( name.empty())
{
cerr << "(nullController): не задан ObjectId!!! (--name)\n";
return 0;
}
ObjectId ID = conf->oind->getIdByName(conf->getControllersSection() + "/" + name);
ObjectId ID = conf->oind->getIdByName(conf->getControllersSection() + "/" + name);
if( ID == uniset::DefaultObjectId )
{
cerr << "(nullController): идентификатор '" << name
<< "' не найден в конф. файле!"
<< " в секции " << conf->getControllersSection() << endl;
return 0;
}
if( ID == uniset::DefaultObjectId )
{
cerr << "(nullController): идентификатор '" << name
<< "' не найден в конф. файле!"
<< " в секции " << conf->getControllersSection() << endl;
return 0;
}
// определяем ask-файл
string askfile = conf->getArgParam("--askfile");
// определяем ask-файл
string askfile = conf->getArgParam("--askfile");
if( askfile.empty())
askfile = conf->getConfFileName();
if( askfile.empty())
askfile = conf->getConfFileName();
// определяем фильтр
string s_field = conf->getArgParam("--s-filter-field");
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 s_field = conf->getArgParam("--s-filter-field");
string s_fvalue = conf->getArgParam("--s-filter-value");
string c_field = conf->getArgParam("--c-filter-field");
string c_fvalue = conf->getArgParam("--c-filter-value");
// надо ли писать изменения в БД
bool dbDumping = conf->getArgInt("--dbDumping");
// надо ли писать изменения в БД
bool dbDumping = conf->getArgInt("--dbDumping");
auto nc = make_shared<NullController>(ID, askfile, s_field, s_fvalue, c_field, c_fvalue, dbDumping);
auto act = UniSetActivator::Instance();
act->add(nc);
act->run(false);
return 0;
}
catch( const std::exception& ex )
{
cerr << "(nullController::main): " << ex.what() << endl;
}
catch(...)
{
cerr << "(nullController::main): catch ..." << endl;
}
auto nc = make_shared<NullController>(ID, askfile, s_field, s_fvalue, c_field, c_fvalue, dbDumping);
auto act = UniSetActivator::Instance();
act->add(nc);
act->run(false);
return 0;
}
catch( const std::exception& ex )
{
cerr << "(nullController::main): " << ex.what() << endl;
}
catch(...)
{
cerr << "(nullController::main): catch ..." << endl;
}
return 1;
return 1;
}
......@@ -9,57 +9,57 @@ using namespace std;
// -----------------------------------------------------------------------------
int main( int argc, const char** argv )
{
// std::ios::sync_with_stdio(false);
// std::ios::sync_with_stdio(false);
try
{
if( argc > 1 && ( !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h") ) )
{
cout << "Usage: uniset-smonit [ args ] --sid id1@node1,Sensor2@node2,id2,sensorname3,... " << endl
<< "Args: " << endl
<< " --confile confilename - Default: configure.xml" << endl
<< " --name XXX - name for smonit. Default: TestProc" << endl;
// << " --script scriptname \n"
return 0;
}
try
{
if( argc > 1 && ( !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h") ) )
{
cout << "Usage: uniset-smonit [ args ] --sid id1@node1,Sensor2@node2,id2,sensorname3,... " << endl
<< "Args: " << endl
<< " --confile confilename - Default: configure.xml" << endl
<< " --name XXX - name for smonit. Default: TestProc" << endl;
// << " --script scriptname \n"
return 0;
}
auto conf = uniset_init(argc, argv, "configure.xml");
auto conf = uniset_init(argc, argv, "configure.xml");
ObjectId ID(DefaultObjectId);
string name = conf->getArgParam("--name", "TestProc");
ObjectId ID(DefaultObjectId);
string name = conf->getArgParam("--name", "TestProc");
ID = conf->getObjectID(name);
ID = conf->getObjectID(name);
if( ID == uniset::DefaultObjectId )
{
cerr << "(main): идентификатор '" << name
<< "' не найден в конф. файле!"
<< " в секции " << conf->getObjectsSection() << endl;
return 0;
}
if( ID == uniset::DefaultObjectId )
{
cerr << "(main): идентификатор '" << name
<< "' не найден в конф. файле!"
<< " в секции " << conf->getObjectsSection() << endl;
return 0;
}
auto act = UniSetActivator::Instance();
auto smon = make_shared<SMonitor>(ID);
act->add(smon);
auto act = UniSetActivator::Instance();
auto smon = make_shared<SMonitor>(ID);
act->add(smon);
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
act->run(false);
return 0;
}
catch( const uniset::Exception& ex )
{
cout << "(main):" << ex << endl;
}
catch( const std::exception& ex )
{
cout << "(main): exception: " << ex.what() << endl;
}
catch(...)
{
cout << "(main): Unknown exception!!" << endl;
}
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
act->run(false);
return 0;
}
catch( const uniset::Exception& ex )
{
cout << "(main):" << ex << endl;
}
catch( const std::exception& ex )
{
cout << "(main): exception: " << ex.what() << endl;
}
catch(...)
{
cout << "(main): Unknown exception!!" << endl;
}
return 1;
return 1;
}
// ------------------------------------------------------------------------------------------
......@@ -8,49 +8,49 @@ using namespace std;
// --------------------------------------------------------------------------
static void short_usage()
{
cout << "Usage: uniset-sviewer-text [--fullname] [--polltime msec] [--confile uniset-confile]\n";
cout << "Usage: uniset-sviewer-text [--fullname] [--polltime msec] [--confile uniset-confile]\n";
}
// --------------------------------------------------------------------------
int main(int argc, const char** argv)
{
// std::ios::sync_with_stdio(false);
try
{
if( argc > 1 && !strcmp(argv[1], "--help") )
{
short_usage();
return 0;
}
auto conf = uniset_init(argc, argv, "configure.xml");
bool fullname = false;
if( findArgParam("--fullname", conf->getArgc(), conf->getArgv()) != -1 )
fullname = true;
SViewer sv(conf->getControllersSection(), !fullname);
timeout_t timeMS = conf->getArgInt("--polltime");
if( timeMS )
{
cout << "(main): просматриваем с периодом " << timeMS << "[мсек]" << endl;
sv.monitor(timeMS);
}
else
sv.view();
return 0;
}
catch( const std::exception& ex )
{
cerr << "(main): Поймали исключение " << ex.what() << endl;
}
catch(...)
{
cerr << "(main): Неизвестное исключение!!!!" << endl;
}
return 1;
// std::ios::sync_with_stdio(false);
try
{
if( argc > 1 && !strcmp(argv[1], "--help") )
{
short_usage();
return 0;
}
auto conf = uniset_init(argc, argv, "configure.xml");
bool fullname = false;
if( findArgParam("--fullname", conf->getArgc(), conf->getArgv()) != -1 )
fullname = true;
SViewer sv(conf->getControllersSection(), !fullname);
timeout_t timeMS = conf->getArgInt("--polltime");
if( timeMS )
{
cout << "(main): просматриваем с периодом " << timeMS << "[мсек]" << endl;
sv.monitor(timeMS);
}
else
sv.view();
return 0;
}
catch( const std::exception& ex )
{
cerr << "(main): Поймали исключение " << ex.what() << endl;
}
catch(...)
{
cerr << "(main): Неизвестное исключение!!!!" << endl;
}
return 1;
}
......@@ -11,100 +11,100 @@ using namespace std;
// -------------------------------------------------------------------------
static struct option longopts[] =
{
{ "help", no_argument, 0, 'h' },
{ "iaddr", required_argument, 0, 'i' },
{ "port", required_argument, 0, 'p' },
{ "verbose", no_argument, 0, 'v' },
{ NULL, 0, 0, 0 }
{ "help", no_argument, 0, 'h' },
{ "iaddr", required_argument, 0, 'i' },
{ "port", required_argument, 0, 'p' },
{ "verbose", no_argument, 0, 'v' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h - this message\n");
printf("-v - Print all messages to stdout\n");
printf("-i addr - LogServer ip or hostname. Default: localhost.\n");
printf("-p port - LogServer port. Default: 3333.\n");
printf("-h - this message\n");
printf("-v - Print all messages to stdout\n");
printf("-i addr - LogServer ip or hostname. Default: localhost.\n");
printf("-p port - LogServer port. Default: 3333.\n");
}
// --------------------------------------------------------------------------
int main( int argc, char* argv[], char* envp[] )
{
int optindex = 0;
int opt = 0;
int verb = 0;
string addr("localhost");
int port = 3333;
int optindex = 0;
int opt = 0;
int verb = 0;
string addr("localhost");
int port = 3333;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hvi:p:", longopts, &optindex);
try
{
while(1)
{
opt = getopt_long(argc, argv, "hvi:p:", longopts, &optindex);
if( opt == -1 )
break;
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'i':
addr = string(optarg);
break;
case 'i':
addr = string(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'v':
verb = 1;
break;
case 'v':
verb = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
cout << "(init): listen " << addr << ":" << port << endl;
if( verb )
cout << "(init): listen " << addr << ":" << port << endl;
auto log = make_shared<DebugStream>();
LogServer ls(log);
auto log = make_shared<DebugStream>();
LogServer ls(log);
ls.async_run(addr, port);
ls.async_run(addr, port);
char buf[10000];
char buf[10000];
while( true )
{
ssize_t r = read(fileno(stdin), buf, sizeof(buf) - 1);
while( true )
{
ssize_t r = read(fileno(stdin), buf, sizeof(buf) - 1);
if( r > 0 )
{
buf[r] = '\0';
log->any() << buf;
}
}
}
catch( const SystemError& err )
{
cerr << "(log-stdin): " << err << endl;
return 1;
}
catch( const uniset::Exception& ex )
{
cerr << "(log-stdin): " << ex << endl;
return 1;
}
catch(...)
{
cerr << "(log-stdin): catch(...)" << endl;
return 1;
}
if( r > 0 )
{
buf[r] = '\0';
log->any() << buf;
}
}
}
catch( const SystemError& err )
{
cerr << "(log-stdin): " << err << endl;
return 1;
}
catch( const uniset::Exception& ex )
{
cerr << "(log-stdin): " << ex << endl;
return 1;
}
catch(...)
{
cerr << "(log-stdin): catch(...)" << endl;
return 1;
}
return 0;
return 0;
}
// --------------------------------------------------------------------------
......@@ -16,106 +16,106 @@ using namespace std;
// -------------------------------------------------------------------------
static void print_help()
{
printf("\n");
printf("Usage: uniset2-logserver-wrap listen-addr listen-port PROGRAMM ARGS..\n");
printf("\n");
printf("\n");
printf("Usage: uniset2-logserver-wrap listen-addr listen-port PROGRAMM ARGS..\n");
printf("\n");
}
// --------------------------------------------------------------------------
int main( int argc, char* argv[], char* envp[] )
{
if( argc < 4 )
{
print_help();
return 1;
}
string addr(argv[1]);
int port = atoi(argv[2]);
int pid;
int cp[2]; /* Child to parent pipe */
if( pipe(cp) < 0)
{
perror("Can't make pipe");
exit(1);
}
try
{
switch( pid = fork() )
{
case -1:
{
perror("Can't fork");
exit(1);
}
case 0:
{
/* Child. */
close(cp[0]);
close( fileno(stdout) );
dup2(cp[1], fileno(stdout));
close( fileno(stderr) );
dup2(fileno(stdout), fileno(stderr));
execvpe(argv[3], argv + 3, envp);
perror("No exec");
kill(getppid(), SIGQUIT);
exit(1);
}
break;
default:
{
/* Parent. */
close(cp[1]);
auto zlog = make_shared<DebugStream>();
zlog->addLevel(Debug::ANY);
LogServer ls(zlog);
cout << "wrap: server " << addr << ":" << port << endl;
ls.async_run( addr, port );
char buf[5000];
while( true )
{
ssize_t r = read(cp[0], &buf, sizeof(buf) - 1 );
if( r > 0 )
{
buf[r] = '\0';
zlog->any() << buf;
}
}
exit(0);
}
break;
}
}
catch( const SystemError& err )
{
cerr << "(logserver-wrap): " << err << endl;
return 1;
}
catch( const uniset::Exception& ex )
{
cerr << "(logserver-wrap): " << ex << endl;
return 1;
}
catch(...)
{
cerr << "(logserver-wrap): catch(...)" << endl;
return 1;
}
return 0;
if( argc < 4 )
{
print_help();
return 1;
}
string addr(argv[1]);
int port = atoi(argv[2]);
int pid;
int cp[2]; /* Child to parent pipe */
if( pipe(cp) < 0)
{
perror("Can't make pipe");
exit(1);
}
try
{
switch( pid = fork() )
{
case -1:
{
perror("Can't fork");
exit(1);
}
case 0:
{
/* Child. */
close(cp[0]);
close( fileno(stdout) );
dup2(cp[1], fileno(stdout));
close( fileno(stderr) );
dup2(fileno(stdout), fileno(stderr));
execvpe(argv[3], argv + 3, envp);
perror("No exec");
kill(getppid(), SIGQUIT);
exit(1);
}
break;
default:
{
/* Parent. */
close(cp[1]);
auto zlog = make_shared<DebugStream>();
zlog->addLevel(Debug::ANY);
LogServer ls(zlog);
cout << "wrap: server " << addr << ":" << port << endl;
ls.async_run( addr, port );
char buf[5000];
while( true )
{
ssize_t r = read(cp[0], &buf, sizeof(buf) - 1 );
if( r > 0 )
{
buf[r] = '\0';
zlog->any() << buf;
}
}
exit(0);
}
break;
}
}
catch( const SystemError& err )
{
cerr << "(logserver-wrap): " << err << endl;
return 1;
}
catch( const uniset::Exception& ex )
{
cerr << "(logserver-wrap): " << ex << endl;
return 1;
}
catch(...)
{
cerr << "(logserver-wrap): catch(...)" << endl;
return 1;
}
return 0;
}
// --------------------------------------------------------------------------
......@@ -7,16 +7,16 @@ using namespace std;
// --------------------------------------------------------------------------
int main( int argc, char** argv )
{
if( argc < 2 || (argc > 1 && ( !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) ) // -V560
{
cout << "Usage: lo2gval [ info,warn,crit,level1...level9,init,repository,system,exception | any ]" << endl;
return 0;
}
if( argc < 2 || (argc > 1 && ( !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) ) // -V560
{
cout << "Usage: lo2gval [ info,warn,crit,level1...level9,init,repository,system,exception | any ]" << endl;
return 0;
}
const string s(argv[1]);
const string s(argv[1]);
cout << (int)Debug::value(s) << endl;
cout << (int)Debug::value(s) << endl;
return 0;
return 0;
}
// --------------------------------------------------------------------------
......@@ -8,42 +8,42 @@ using namespace std;
// -----------------------------------------------------------------------------
int main( int argc, const char** argv )
{
try
{
auto conf = uniset_init(argc, argv);
try
{
auto conf = uniset_init(argc, argv);
xmlNode* cnode = conf->getNode("Skel");
xmlNode* cnode = conf->getNode("Skel");
if( cnode == NULL )
{
cerr << "(Skel): not found <Skel> in conffile" << endl;
return 1;
}
if( cnode == NULL )
{
cerr << "(Skel): not found <Skel> in conffile" << endl;
return 1;
}
auto o = make_shared<Skel>("Skel", cnode);
auto o = make_shared<Skel>("Skel", cnode);
auto act = UniSetActivator::Instance();
act->add(o);
auto act = UniSetActivator::Instance();
act->add(o);
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
ulogany << "\n\n\n";
ulogany << "(Skel::main): -------------- Skel START -------------------------\n\n";
dlogany << "\n\n\n";
dlogany << "(Skel::main): -------------- Skel START -------------------------\n\n";
act->run(false);
return 0;
}
catch( const std::exception& ex )
{
cerr << "(Skel::main): " << ex.what() << endl;
}
catch(...)
{
cerr << "(Skel::main): catch(...)" << endl;
}
ulogany << "\n\n\n";
ulogany << "(Skel::main): -------------- Skel START -------------------------\n\n";
dlogany << "\n\n\n";
dlogany << "(Skel::main): -------------- Skel START -------------------------\n\n";
act->run(false);
return 0;
}
catch( const std::exception& ex )
{
cerr << "(Skel::main): " << ex.what() << endl;
}
catch(...)
{
cerr << "(Skel::main): catch(...)" << endl;
}
return 1;
return 1;
}
// -----------------------------------------------------------------------------
......@@ -5,7 +5,7 @@ using namespace std;
using namespace uniset;
// -----------------------------------------------------------------------------
Skel::Skel( uniset::ObjectId id, xmlNode* confnode ):
Skel_SK( id, confnode )
Skel_SK( id, confnode )
{
}
// -----------------------------------------------------------------------------
......@@ -15,8 +15,8 @@ Skel::~Skel()
// -----------------------------------------------------------------------------
Skel::Skel()
{
cerr << "(Skel): init failed!!!!!!!!!!!!!!!" << endl;
throw Exception();
cerr << "(Skel): init failed!!!!!!!!!!!!!!!" << endl;
throw Exception();
}
// -----------------------------------------------------------------------------
void Skel::step()
......
......@@ -5,21 +5,21 @@
#include "Skel_SK.h"
// -----------------------------------------------------------------------------
class Skel:
public Skel_SK
public Skel_SK
{
public:
Skel( uniset::ObjectId id, xmlNode* confnode = uniset::uniset_conf()->getNode("Skel") );
virtual ~Skel();
public:
Skel( uniset::ObjectId id, xmlNode* confnode = uniset::uniset_conf()->getNode("Skel") );
virtual ~Skel();
protected:
Skel();
protected:
Skel();
virtual void step() override;
virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
virtual void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void askSensors( UniversalIO::UIOCommand cmd ) override;
virtual void step() override;
virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
virtual void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void askSensors( UniversalIO::UIOCommand cmd ) override;
private:
private:
};
// -----------------------------------------------------------------------------
#endif // Skel_H_
......
......@@ -5,29 +5,29 @@ using namespace std;
using namespace uniset;
// -----------------------------------------------------------------------------
TestGen::TestGen( uniset::ObjectId id, xmlNode* confnode ):
TestGen_SK( id, confnode )
TestGen_SK( id, confnode )
{
vmonit(int_var);
vmonit(bool_var);
vmonit(int_var);
vmonit(bool_var);
const long* i = valptr(input2_s);
long* k = outptr(output1_c);
const long* i = valptr(input2_s);
long* k = outptr(output1_c);
if( !k )
cerr << "output1_c NOT FOUND!!!" << endl;
if( !k )
cerr << "output1_c NOT FOUND!!!" << endl;
ObjectId d = idval(in_input2_s);
ObjectId d2 = idval(&in_input2_s);
ObjectId d3 = idval(i);
ObjectId d4 = idval(&out_output1_c);
ObjectId d = idval(in_input2_s);
ObjectId d2 = idval(&in_input2_s);
ObjectId d3 = idval(i);
ObjectId d4 = idval(&out_output1_c);
if( !i )
cerr << "input2_s NOT FOUND!!!" << endl;
else
cerr << "input2_s=" << (*i) << " d=" << d << " d2=" << d2 << " d3=" << d3 << " input2_s=" << input2_s << endl;
if( !i )
cerr << "input2_s NOT FOUND!!!" << endl;
else
cerr << "input2_s=" << (*i) << " d=" << d << " d2=" << d2 << " d3=" << d3 << " input2_s=" << input2_s << endl;
vmonit(t_val);
vmonit(t_val);
}
// -----------------------------------------------------------------------------
TestGen::~TestGen()
......@@ -36,61 +36,61 @@ TestGen::~TestGen()
// -----------------------------------------------------------------------------
TestGen::TestGen()
{
cerr << ": init failed!!!!!!!!!!!!!!!" << endl;
throw Exception();
cerr << ": init failed!!!!!!!!!!!!!!!" << endl;
throw Exception();
}
// -----------------------------------------------------------------------------
void TestGen::step()
{
#if 0
cout << "strval: " << strval(input2_s) << endl;
cout << "str: " << str(input2_s) << endl;
cout << "===========" << endl;
cout << dumpIO() << endl;
cout << "strval: " << strval(input2_s) << endl;
cout << "str: " << str(input2_s) << endl;
cout << "===========" << endl;
cout << dumpIO() << endl;
myinfo << str(input2_s) << endl;
ulog()->info() << "ulog: " << str(input2_s) << endl;
myinfo << str(input2_s) << endl;
ulog()->info() << "ulog: " << str(input2_s) << endl;
int_var++;
bool_var ^= true;
cout << vmon << endl;
int_var++;
bool_var ^= true;
cout << vmon << endl;
#endif
// cout << vmon.pretty_str() << endl;
// cout << vmon.pretty_str() << endl;
}
// -----------------------------------------------------------------------------
void TestGen::sensorInfo( const SensorMessage* sm )
{
if( sm->id == input1_s )
out_output1_c = in_input1_s; // sm->state
if( sm->id == input1_s )
out_output1_c = in_input1_s; // sm->state
}
// -----------------------------------------------------------------------------
void TestGen::timerInfo( const TimerMessage* tm )
{
if( tm->id == 1 )
{
askTimer(1, 0);
askTimer(2, 3000);
}
else if( tm->id == 2 )
{
askTimer(1, 2000);
askTimer(2, 0);
}
if( tm->id == 1 )
{
askTimer(1, 0);
askTimer(2, 3000);
}
else if( tm->id == 2 )
{
askTimer(1, 2000);
askTimer(2, 0);
}
}
// -----------------------------------------------------------------------------
#ifndef DISABLE_REST_API
void TestGen::httpGetUserData( Poco::JSON::Object::Ptr& jdata )
{
jdata->set("myMode", "RUNNING");
jdata->set("myVar", 42);
jdata->set("myFloatVar", 42.42);
jdata->set("myMessage", "This is text fot test httpGetUserData");
jdata->set("myMode", "RUNNING");
jdata->set("myVar", 42);
jdata->set("myFloatVar", 42.42);
jdata->set("myMessage", "This is text fot test httpGetUserData");
}
#endif
// -----------------------------------------------------------------------------
void TestGen::sysCommand( const uniset::SystemMessage* sm )
{
if( sm->command == SystemMessage::StartUp )
askTimer(1, 2000);
if( sm->command == SystemMessage::StartUp )
askTimer(1, 2000);
}
// -----------------------------------------------------------------------------
......@@ -5,26 +5,26 @@
#include "TestGen_SK.h"
// -----------------------------------------------------------------------------
class TestGen:
public TestGen_SK
public TestGen_SK
{
public:
TestGen( uniset::ObjectId id, xmlNode* confnode = uniset::uniset_conf()->getNode("TestGen") );
virtual ~TestGen();
public:
TestGen( uniset::ObjectId id, xmlNode* confnode = uniset::uniset_conf()->getNode("TestGen") );
virtual ~TestGen();
protected:
TestGen();
protected:
TestGen();
virtual void step() override;
virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
virtual void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
virtual void step() override;
virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
virtual void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
#ifndef DISABLE_REST_API
virtual void httpGetUserData( Poco::JSON::Object::Ptr& jdata ) override;
virtual void httpGetUserData( Poco::JSON::Object::Ptr& jdata ) override;
#endif
private:
bool bool_var = { false };
int int_var = {0};
uniset::timeout_t t_val = { 0 };
private:
bool bool_var = { false };
int int_var = {0};
uniset::timeout_t t_val = { 0 };
};
// -----------------------------------------------------------------------------
#endif // TestGen_H_
......
......@@ -5,7 +5,7 @@ using namespace std;
using namespace uniset;
// -----------------------------------------------------------------------------
TestGenAlone::TestGenAlone( uniset::ObjectId id, xmlNode* confnode ):
TestGenAlone_SK( id, confnode )
TestGenAlone_SK( id, confnode )
{
}
// -----------------------------------------------------------------------------
......@@ -15,13 +15,13 @@ TestGenAlone::~TestGenAlone()
// -----------------------------------------------------------------------------
void TestGenAlone::step()
{
cout << strval(in_input2_s) << endl;
cout << strval(in_input2_s) << endl;
}
// -----------------------------------------------------------------------------
void TestGenAlone::sensorInfo( const SensorMessage* sm )
{
if( sm->id == input1_s )
out_output1_c = in_input1_s; // sm->state
if( sm->id == input1_s )
out_output1_c = in_input1_s; // sm->state
}
// -----------------------------------------------------------------------------
void TestGenAlone::timerInfo( const TimerMessage* tm )
......
......@@ -5,19 +5,19 @@
#include "TestGenAlone_SK.h"
// -----------------------------------------------------------------------------
class TestGenAlone:
public TestGenAlone_SK
public TestGenAlone_SK
{
public:
TestGenAlone( uniset::ObjectId id, xmlNode* confnode = uniset::uniset_conf()->getNode("TestGenAlone") );
virtual ~TestGenAlone();
public:
TestGenAlone( uniset::ObjectId id, xmlNode* confnode = uniset::uniset_conf()->getNode("TestGenAlone") );
virtual ~TestGenAlone();
protected:
virtual void step() override;
void sensorInfo( const uniset::SensorMessage* sm ) override;
void timerInfo( const uniset::TimerMessage* tm ) override;
protected:
virtual void step() override;
void sensorInfo( const uniset::SensorMessage* sm ) override;
void timerInfo( const uniset::TimerMessage* tm ) override;
private:
private:
};
// -----------------------------------------------------------------------------
#endif // TestGenAlone_H_
......
......@@ -32,9 +32,10 @@ AC_ENABLE_SHARED(yes)
AC_ENABLE_STATIC(no)
AM_PROG_LIBTOOL
ASTYLE_OPT="-A1 -T -C -S -N -L -w -Y -M -f -p --mode=c --lineend=linux --align-reference=type --align-pointer=type --suffix=none --style=ansi"
ASTYLE_OPT="-A1 -T -C -S -L -w -N -Y -M -f -p --mode=c --lineend=linux --align-reference=type --align-pointer=type --suffix=none --style=ansi --convert-tabs -s4"
AC_SUBST(ASTYLE_OPT)
# Checks for libraries.
PKG_CHECK_MODULES(XML, libxml-2.0)
PKG_CHECK_MODULES(OMNI, omniORB4)
......
/*! \page ConfigurationPage Конфигурирование системы
- \ref ConfigurationPage_secCommon
- \ref ConfigurationPage_secOmniORB
- \ref ConfigurationPage_secCommon
- \ref ConfigurationPage_secOmniORB
\section ConfigurationPage_secCommon Общее описание
\section ConfigurationPage_secCommon Общее описание
Для конфигурирования системы используется файл (обычно "configure.xml").
Конфигурация является глобальным объектом. Для получения доступа к ней используется функция auto conf = uniset_conf();
До начала работы, обычно в функции main(), конфигурация должна быть инициализирована при помощи функции uniset_init().
При этом третий параметр, указывающий название конфигурационного файла, является не обязательным.
По умолчанию обрабатывается аргумент командной строки --confile filename.
Для конфигурирования системы используется файл (обычно "configure.xml").
Конфигурация является глобальным объектом. Для получения доступа к ней используется функция auto conf = uniset_conf();
До начала работы, обычно в функции main(), конфигурация должна быть инициализирована при помощи функции uniset_init().
При этом третий параметр, указывающий название конфигурационного файла, является не обязательным.
По умолчанию обрабатывается аргумент командной строки --confile filename.
\code
...
#include <Configuration.h>
......@@ -20,41 +20,39 @@ int main(int argc, char **argv)
{
try
{
uniset_init(argc, argv, "configure.xml");
...
...
}
catch(Exception& ex )
uniset_init(argc, argv, "configure.xml");
...
...
}
catch(Exception& ex )
{
cerr << "(main): Поймали исключение " << ex << endl;
cerr << "(main): Поймали исключение " << ex << endl;
}
catch(...)
{
cerr << "Неизвестное исключение!!!!"<< endl;
cerr << "Неизвестное исключение!!!!"<< endl;
}
...
}
...
}
\endcode
\section ConfigurationPage_secOmniORB Конфигурирование OmniORB
Для возможности задать напрямую параметры для omniORB заложена специальная секция <omniORB>.
В данную секцию можно записывать любые параметры поддерживаемые библиотекой omniORB.
Формат и название параметров см. документацию по omniORB.
Пример:
\section ConfigurationPage_secOmniORB Конфигурирование OmniORB
Для возможности задать напрямую параметры для omniORB заложена специальная секция <omniORB>.
В данную секцию можно записывать любые параметры поддерживаемые библиотекой omniORB.
Формат и название параметров см. документацию по omniORB.
Пример:
\code
<omniORB>
<option name="endPoint" arg="giop:tcp:host1:"/>
<option name="endPoint" arg="giop:tcp:host2:" error_if_not_available="1"/>
</omniORB>
<omniORB>
<option name="endPoint" arg="giop:tcp:host1:"/>
<option name="endPoint" arg="giop:tcp:host2:" error_if_not_available="1"/>
</omniORB>
\endcode
Для параметра 'endPoint' встроена дополнительная проверка доступности указанной адреса.
\warning По умолчанию \b недоступность \b игнорируется, если не указан параметр \a error_if_not_available="1"
Для параметра 'endPoint' встроена дополнительная проверка доступности указанного адреса.
\warning По умолчанию \b недоступность \b игнорируется, если не указан параметр \a error_if_not_available="1"
Помимо этого можно задать параметр \a ignore_checking="1", чтобы не происходило проверки доступности endPoint.
Помимо этого можно задать параметр \a ignore_checking="1", чтобы не происходило проверки доступности endPoint.
*/
\ No newline at end of file
/*! \page DebugPage Описание использования функций отладки
Класс для вывода отладочных сообщений называется DebugStream.
Сообщения могут выводится на экран и в файл, отбираться по
определённым критериям и до определённого уровня.
Класс для вывода отладочных сообщений называется DebugStream.
Сообщения могут выводится на экран и в файл, отбираться по
определённым критериям и до определённого уровня.
- \ref subUsing
- \ref subConf
- \ref subUsing
- \ref subConf
\subsection subUsing Использование
Для использования нужно создать свой объект класса DebugStream или
использовать глобальный объект UniSetTypes::unideb.
Для переключения вывода отладки в файл, используйте функцию logFile(char const *f);
Описание всех имеющихся функций находится в файле DebugStream.h
на английском языке.
\subsection subUsing Использование
Для использования нужно создать свой объект класса DebugStream или
использовать глобальный объект UniSetTypes::unideb.
Для переключения вывода отладки в файл, используйте функцию logFile(char const *f);
Функция unideb[...] по умолчанию выводит в строку дату и время.
Функция unideb(...) просто выводит строку (в конец предыдущему потоку).
\par Пример использования:
\code
#include "Debug.h"
#include "Configuration.h"
using namespace UniSetTypes;
...
unideb << "Этот текст будет выведен на экран в любом случае";
unideb.addLevel(Debug::CRIT); // показывать CRIT
unideb[Debug::CRIT] << "Этот текст будет выведен при разрешении выводить сообщения уровня CRIT";
unideb.delLevel(Debug::CRIT); // больше не показывать CRIT
// Отладочное сообщение будет выводиться при установленном уровне INFO или CRIT"
unideb[Debug::type(Debug::INFO | Debug::CRIT)] << "Отладочное сообщение";
Описание всех имеющихся функций находится в файле DebugStream.h
на английском языке.
// Вывод многострочного сообщения
unideb[Debug::INFO] << " вывод с датой и временем ";
unideb(Debug::INFO) << " продолжение вывода без даты и времени " << endl;
\endcode
Функция unideb[...] по умолчанию выводит в строку дату и время.
Функция unideb(...) просто выводит строку (в конец предыдущему потоку).
\par Пример использования:
\code
#include "Debug.h"
#include "Configuration.h"
using namespace UniSetTypes;
...
unideb << "Этот текст будет выведен на экран в любом случае";
unideb.addLevel(Debug::CRIT); // показывать CRIT
unideb[Debug::CRIT] << "Этот текст будет выведен при разрешении выводить сообщения уровня CRIT";
unideb.delLevel(Debug::CRIT); // больше не показывать CRIT
// Отладочное сообщение будет выводиться при установленном уровне INFO или CRIT"
unideb[Debug::type(Debug::INFO | Debug::CRIT)] << "Отладочное сообщение";
Если вы хотите использовать отладочный вывод из критичного к времени
кода, используйте следующую конструкцию:
\code
if (unideb.debugging(Debug::INFO)) {
unideb << "...debug output..." << endl;
}
\endcode
// Вывод многострочного сообщения
unideb[Debug::INFO] << " вывод с датой и временем ";
unideb(Debug::INFO) << " продолжение вывода без даты и времени " << endl;
\endcode
\subsection subConf Конфигурирование логов
Конфигурирование логов можно производить, при помощи файла конфигурации или через командную строку.
Например UniSetTypes::unideb настраивается в конфигурационном файле следующим образом:
Если вы хотите использовать отладочный вывод из критичного к времени
кода, используйте следующую конструкцию:
\code
<UniSetDebug name="unideb" levels="crit,warn" file=""/>
\endcode
При запуске программ используйте ключ "--help" для получения подробной информации
о настройке логов из командной строки
\code
if (unideb.debugging(Debug::INFO)) {
unideb << "...debug output..." << endl;
}
\endcode
\subsection subConf Конфигурирование логов
Конфигурирование логов можно производить, при помощи файла конфигурации или через командную строку.
Например UniSetTypes::unideb настраивается в конфигурационном файле следующим образом:
\code
<UniSetDebug name="unideb" levels="crit,warn" file=""/>
\endcode
При запуске программ используйте ключ "--help" для получения подробной информации
о настройке логов из командной строки
*/
\ No newline at end of file
/*!
\page MutexHowToPage Как пользоваться uniset_mutex и uniset_mutex_lock
\page MutexHowToPage Как пользоваться uniset_mutex и uniset_mutex_lock
\par
"мьютекс"(mutex) - получено от англ. Mutual Exclusive. (нечто вроде "взаимоисключение")
\par
Основными операциями для мьютексов, помимо создания и уничтожения, являются операции lock и unlock.
Логически работа с мьютексом могла бы выглядеть так (псевдокод)
\par
"мьютекс"(mutex) - получено от англ. Mutual Exclusive. (нечто вроде "взаимоисключение")
\par
Основными операциями для мьютексов, помимо создания и уничтожения, являются операции lock и unlock.
Логически работа с мьютексом могла бы выглядеть так (псевдокод)
\code
Mutex mutex;
...
mutex.lock();
DoSomething();
mutex.unlock();
\endcode
Но в общем случае это ни к чему хорошему не приведет, т.к. если в \c DoSomething() возникнет исключение, то
\c mutex.unlock() уже не выполнится. Конечно можно использовать \c try...catch, но желательно, чтобы
код работал независимо от ситуации. Для этого введен класс \b uniset_mutex_lock. При его использовании получается
следующий код (один из вариантов использования):
\code
using namespase UniSetTypes;
...
uniset_mutex mutex;
...
{
uniset_mutex_lock lock(mutex); // вызов mutex.lock() как часть кода конструктора
DoSomething();
} // <-- Заканчивается зона видимости lock-а и происходит вызов mutex.unlock() как часть кода деструктора
\endcode
В этом случае, даже если в \c DoSomethig() будет сгенерировано исключение ресурс будет освобожден
при вызове деструктора. Вот и все решение...
\par
Главное не забывайте ставить скобочки...
\par
Желательно не использовать \c mutex.lock() и \c uniset_mutex.unlock() в чистом виде, а только совместно с
\b uniset_mutex_lock. Кроме особых случаев (см. \ref secWarning).
\par
Следует помнить, что мьютексы \b фактически никаких ресурсов не захватывают, это только флаг означающий,
что ресурс занят. Поэтому работать с ними надо внимательно и не забывать блокировать ресурс там где это надо.
\par
Описания классов см. UniSetTypes::uniset_mutex и UniSetTypes::uniset_mutex_lock
\code
Mutex mutex;
...
mutex.lock();
DoSomething();
mutex.unlock();
\endcode
\section secWarning Особые случаи
Если в \c DoSomethig() будет вызвана \c exit(0), \c abort() или что-нибудь подобное,
то unlock не произойдет. В таком случае следовало бы напрямую вызывать \c unlock() до вызова сигнала, но эти случаи редкие и если
возникнет необходимость, то можно будет вместо \a protected сделать их \a public.
\note Описание составлено на основе описания мьютексов из книги А.Цимбала "Технология CORBA для профессионалов".
Но в общем случае это ни к чему хорошему не приведет, т.к. если в \c DoSomething() возникнет исключение, то
\c mutex.unlock() уже не выполнится. Конечно можно использовать \c try...catch, но желательно, чтобы
код работал независимо от ситуации. Для этого введен класс \b uniset_mutex_lock. При его использовании получается
следующий код (один из вариантов использования):
\code
using namespase UniSetTypes;
...
uniset_mutex mutex;
...
{
uniset_mutex_lock lock(mutex); // вызов mutex.lock() как часть кода конструктора
DoSomething();
} // <-- Заканчивается зона видимости lock-а и происходит вызов mutex.unlock() как часть кода деструктора
\endcode
В этом случае, даже если в \c DoSomethig() будет сгенерировано исключение ресурс будет освобожден
при вызове деструктора. Вот и все решение...
\par
Главное не забывайте ставить скобочки...
\par
Желательно не использовать \c mutex.lock() и \c uniset_mutex.unlock() в чистом виде, а только совместно с
\b uniset_mutex_lock. Кроме особых случаев (см. \ref secWarning).
\par
Следует помнить, что мьютексы \b фактически никаких ресурсов не захватывают, это только флаг означающий,
что ресурс занят. Поэтому работать с ними надо внимательно и не забывать блокировать ресурс там где это надо.
\par
Описания классов см. UniSetTypes::uniset_mutex и UniSetTypes::uniset_mutex_lock
\section secWarning Особые случаи
Если в \c DoSomethig() будет вызвана \c exit(0), \c abort() или что-нибудь подобное,
то unlock не произойдет. В таком случае следовало бы напрямую вызывать \c unlock() до вызова сигнала, но эти случаи редкие и если
возникнет необходимость, то можно будет вместо \a protected сделать их \a public.
\note Описание составлено на основе описания мьютексов из книги А.Цимбала "Технология CORBA для профессионалов".
*/
\ No newline at end of file
/* OBSOLETE DOC!!!
\page ObjectRepositoryPage Репозиторий объектов
\page ObjectRepositoryPage Репозиторий объектов
Репозиторий объектов предназначен для хранения и получения ссылок на объекты, с целью дальнейшего
использования функций предоставленных этими объектами. Объекты регистрирующиеся в репозитории могут быть удаленными...
Репозиторий объектов предназначен для хранения и получения ссылок на объекты, с целью дальнейшего
использования функций предоставленных этими объектами. Объекты регистрирующиеся в репозитории могут быть удаленными...
- \ref subRegCommon
- \ref subReg
- \ref subResolve
- \ref subRegCommon
- \ref subReg
- \ref subResolve
\section subRegCommon Вводная
При наследовании от UniSetObject (и его потомков) регистрация в репозитории происходит автоматически.
Поэтому регистрироваться отдельно нет необходимости.
\section subRegCommon Вводная
При наследовании от UniSetObject (и его потомков) регистрация в репозитории происходит автоматически.
Поэтому регистрироваться отдельно нет необходимости.
\section subReg Регистрация
Для регистрации существует следующие функции.
По текстовому имени
- void ObjectRepository::registration(const ObjectName name, const ObjectPtr oRef, const string section)
- void ObjectRepository::registration(const ObjectName fullName, const ObjectPtr oRef)
\section subReg Регистрация
Для регистрации существует следующие функции.
По текстовому имени
- void ObjectRepository::registration(const ObjectName name, const ObjectPtr oRef, const string section)
- void ObjectRepository::registration(const ObjectName fullName, const ObjectPtr oRef)
По идентификатору
- void UniversalInterface::registered(UniSetTypes::ObjectId id, const UniSetTypes::ObjectPtr oRef)throw(ORepFailed);
- void UniversalInterface::registered(UniSetTypes::ObjectId id, UniSetTypes::ObjectId node, const UniSetTypes::ObjectPtr oRef)throw(ORepFailed);
По идентификатору
- void UniversalInterface::registered(UniSetTypes::ObjectId id, const UniSetTypes::ObjectPtr oRef)throw(ORepFailed);
- void UniversalInterface::registered(UniSetTypes::ObjectId id, UniSetTypes::ObjectId node, const UniSetTypes::ObjectPtr oRef)throw(ORepFailed);
Пример:
\code
#include "ObjectRepository.h"
Пример:
\code
#include "ObjectRepository.h"
...
CORBA::Object_ptr oref;
...
ObjectRepository orep;
try
{
orep.registration("myObject", oref, "Root/Processes");
}
cacth(ORepFailed)
{
cerr << "Не удалось зарегистрировать объект " << endl;
}
\endcode
Или при помощи UniverslaInterface
\code
class MyObject:
public UniSetObject
{
public:
MyObject( UniSetTypes::ObjectId id );
...
protected:
void my_start()
{
try
{
ui.registration(myid, myRef);
}
catch(Exception ex)
{
cout << ex << endl;
}
}
}
\endcode
\section subResolve Получение ссылки на объект
...
CORBA::Object_ptr oref;
...
ObjectRepository orep;
try
{
orep.registration("myObject", oref, "Root/Processes");
}
cacth(ORepFailed)
{
cerr << "Не удалось зарегистрировать объект " << endl;
}
\endcode
Или при помощи UniverslaInterface
\code
class MyObject:
public UniSetObject
{
public:
MyObject( UniSetTypes::ObjectId id );
...
Для получения ссылки лучше всего пользоваться
- UniSetTypes::ObjectPtr UniversalInterface::resolve( UniSetTypes::ObjectId id )
- UniSetTypes::ObjectPtr UniversalInterface::resolve( UniSetTypes::ObjectId id, UniSetTypes::ObjectId nodeName, int timeoutMS=UniversalIO::defaultTimeOut)
throw(ResolveNameError, TimeOut);
protected:
void my_start()
{
try
{
ui.registration(myid, myRef);
}
catch(Exception ex)
{
cout << ex << endl;
}
}
}
\endcode
т.к. UniversalInterface::resolve() пытается получиться ссылку, в том числе через резервный каналы связи.
\section subResolve Получение ссылки на объект
Пример:
\code
...
try
{
CORBA::Object_ptr oref=0;
IOController_i_var ioc = IOController_i::_narrow( ui.resolve(id, node) );
...
}
catch(Exception ex)
{
cout << ex << endl;
}
Для получения ссылки лучше всего пользоваться
- UniSetTypes::ObjectPtr UniversalInterface::resolve( UniSetTypes::ObjectId id )
- UniSetTypes::ObjectPtr UniversalInterface::resolve( UniSetTypes::ObjectId id, UniSetTypes::ObjectId nodeName, int timeoutMS=UniversalIO::defaultTimeOut)
throw(ResolveNameError, TimeOut);
\endcode
т.к. UniversalInterface::resolve() пытается получиться ссылку, в том числе через резервный каналы связи.
Пример:
\code
...
try
{
CORBA::Object_ptr oref=0;
IOController_i_var ioc = IOController_i::_narrow( ui.resolve(id, node) );
...
}
catch(Exception ex)
{
cout << ex << endl;
}
\endcode
*/
\ No newline at end of file
// эти разделы сформируются автоматически из описаний сделанных в соответствующих h-файлах
/*!
\page ServicesPage Сервисы
- \ref secDBServer
\section secDBServer Сервер БД
\sa \ref page_DBServer_MySQL
*/
\ No newline at end of file
/* OBSOLETE DOC!!!
\page UniversalInterfacePage Универсальный интерфейс
Этот интерфейс позволяет получать доступ к объекту по идентификатору(или имени), заказывать датчики, и т.п.
Для работы с удаленными объектами необходимо указывать идентификатор узла, на котором
находится этот объект(если он не задан, идет обращение к локальному).
- \ref secIOControl
- \ref subAsk
- \ref subGet
- \ref subSet
- \ref secTimers
- \ref secORep
\sa UniversalInterface
Этот интерфейс позволяет получать доступ к объекту по идентификатору(или имени), заказывать датчики, и т.п.
Для работы с удаленными объектами необходимо указывать идентификатор узла, на котором
находится этот объект(если он не задан, идет обращение к локальному).
- \ref secIOControl
- \ref subAsk
- \ref subGet
- \ref subSet
- \ref secTimers
- \ref secORep
\sa UniversalInterface
\section secIOControl Функции работы с вводом/выводом
\subsection subAsk Заказ датчиков
\subsection subAsk Заказ датчиков
Заказ датчиков осуществляется при помощи функций:
Заказ датчиков осуществляется при помощи функций:
для дискретных датчиков
- \ref void UniversalInterface::askState(...)
для дискретных датчиков
- \ref void UniversalInterface::askState(...)
для аналоговых датчиков
- \ref void UniversalInterface::askValue(...)
\subsection subGet Получение информации о текущем состоянии датчика
Информацию о состоянии датчика можно получить при помощи функций:
для аналоговых датчиков
- \ref void UniversalInterface::askValue(...)
\subsection subGet Получение информации о текущем состоянии датчика
Информацию о состоянии датчика можно получить при помощи функций:
для дискретных датчиков
- \ref void UniversalInterface::getState(...)
для дискретных датчиков
- \ref void UniversalInterface::getState(...)
для аналоговых датчиков
- \ref void UniversalInterface::getValue(...)
для аналоговых датчиков
- \ref void UniversalInterface::getValue(...)
\subsection subSet Управление выходными сигналом
\subsection subSet Управление выходными сигналом
для дискретных датчиков
- \ref void UniversalInterface::setState(...)
для дискретных датчиков
- \ref void UniversalInterface::setState(...)
для аналоговых датчиков
- \ref void UniversalInterface::setValue(...)
для аналоговых датчиков
- \ref void UniversalInterface::setValue(...)
\section secORep Функции работы с репозиторием объектов
- \ref void UniversalInterface::registered(...)
- \ref void UniversalInterface::unregister(...)
- \ref void UniversalInterface::resolve(...)
- \ref ObjectId UniversalInterface::getIdByName(...)
- \ref const char* UniversalInterface::getNameById(...)
- \ref void UniversalInterface::registered(...)
- \ref void UniversalInterface::unregister(...)
- \ref void UniversalInterface::resolve(...)
- \ref ObjectId UniversalInterface::getIdByName(...)
- \ref const char* UniversalInterface::getNameById(...)
\section secTimers Заказ таймеров
- \ref void UniversalInterface::askTimer(...)
- \ref void UniversalInterface::askTimer(...)
*/
/*!
\page DependsPage Зависимости между датчиками
Существует два механизма реализующих зависимость между датчиками:
Существует два механизма реализующих зависимость между датчиками:
- \ref pgDep_secIOControl
- \ref pgDep_secIOBase
\section pgDep_secIOControl Зависимость на уровне IOController (SharedMemmory)
\section pgDep_secIOControl Зависимость на уровне IOController (SharedMemmory)
Механизм зависимостей реализован в классе IOController.
Механизм зависимостей реализован в классе IOController.
Пример записи "зависимости" в configure.xml:
Пример записи "зависимости" в configure.xml:
\code
<item textname="...." iotype="..." .../>
<consumers>
<consumers>
<depends>
<depend name="Sensor1" filter="val" />
<depend name="Sensor2" filter2="val1" />
</depends>
</item>
<item textname="...." iotype="..." .../>
<consumers>
<consumers>
<depends>
<depend name="Sensor1" filter="val" />
<depend name="Sensor2" filter2="val1" />
</depends>
</item>
\endcode
При считывании конф. файла можно задавать фильтры.
ПОКА РЕАЛИЗОВАНА ЗАВИСИМОСТЬ ТОЛЬКО ОТ ОДНОГО ДАТЧИКА!
т.е. <depend> может быть только один.
\section pgDep_secIOBase Зависимость на уровне IOBase
Механизм зависимостей между датчиками на уровне IOBase,
При считывании конф. файла можно задавать фильтры.
ПОКА РЕАЛИЗОВАНА ЗАВИСИМОСТЬ ТОЛЬКО ОТ ОДНОГО ДАТЧИКА!
т.е. <depend> может быть только один.
\section pgDep_secIOBase Зависимость на уровне IOBase
Механизм зависимостей между датчиками на уровне IOBase,
работает на уровне процессов обмена использующих IOBase.
В ним относятся IOControl, ModbusMaster (RTU,TCP) и т.п.
Плюсом данного механизма является, то, что он обеспечивает
......@@ -42,9 +42,9 @@
Следует иметь ввиду, что этот механизм не действует при сохранении значений, например при помощи uniset-admin,
в отличие от механизма \ref pgDep_secIOControl
Пример записи "зависимости" в configure.xml:
Пример записи "зависимости" в configure.xml:
\code
<item textname="...." iotype="..." ... depend="OtherSensor_AS" depend_value="2" />
<item textname="...." iotype="..." ... depend="OtherSensor_AS" depend_value="2" />
\endcode
В данном случае подразумевается, что разрешающим датчиком является OtherSensor_AS=2.
......
/*! \page page_Uniset Краткое описание библиотеки libuniset
- \ref pg_UniSet_Common
- \ref pg_Uniset_Processes
- \ref pg_UniSet_Network
- \ref pg_UniSet_Utilities
- \ref pg_UniSet_Common
- \ref pg_Uniset_Processes
- \ref pg_UniSet_Network
- \ref pg_UniSet_Utilities
\section pg_UniSet_Common Общее описание libuniset
......
/*!
\mainpage
\mainpage
\image html uniset.png
\image html uniset.png
\section MainSection Оглавление
\section MainSection Оглавление
- \ref page_Concept
- \ref page_Uniset
- \ref UniSetLibStylePage
- \ref page_Concept
- \ref page_Uniset
- \ref UniSetLibStylePage
*/
/*!
\page ToDoPage Необходимо доделать
\page ToDoPage Необходимо доделать
-# утилиты мониторинга работы системы
-# настройку "политик" для ORB сделать из конф. файла
-# по максимуму переход на xml
-# дополнить описание IOController-ов разделом про XML-файл заказчиков(создание,работа)
-# сделать описание принципов и деталей межобъектного взаимодействия
(об ограничениях на размер сообщений, очередь сообщений, приоритеты и т.п.)
-# попытаться сделать работу с сервисами более универсальной
(что то типа "UniSetTypes::ObjectId conf->getService(const string name)" )
-# откорректировать и дописать "общее описание" библиотеки
-# сделать тип в UniSetObject::getType string-ом
(для универсальности и простоты будущих расширений)
-# переписать тестовые примеры, под текущую ситуацию.
-# в будущем попытаться отказаться от ObjectId и перейти на строки (это надо ещё обдумать)
-# в InfoServer-е по routeList-у сообщения пересылаются, только если они локальные.
Надо переделать механизм, чтобы можно было отделять тех кому пересылать все сообщения,
от тех кому пересылать только локальные....
-# Для IOController-ов разработать спец. интерфейс для работы с датчиками (сохранение, получение состояния и т.п.)
Для того, чтобы можно было использовать разные способы хранения (БД, STL-контейнеры, файлы и т.п.). Т.к. сейчас
жёсткая реализация на STL-контейнерах.
-# дописать Mutex как надо (или перейти на omni_mutex-ы) . Сделать RWMutex и RMutex.
-# стартовые скрипты для локальной отладки (откорректировать старые)
-# управление очередью сообщений, очистка по фильтру и т.п. (может перейти на несколько очередей по приоритетам)
-# У NotifyController-а две функции с название calibrate (надо переименовать)
-# Сделать свойство tick у процессов обмена по Modbus, чтобы можно было с разной периодичностью опрашивать разные регистры
-# утилиты мониторинга работы системы
-# настройку "политик" для ORB сделать из конф. файла
-# по максимуму переход на xml
-# дополнить описание IOController-ов разделом про XML-файл заказчиков(создание,работа)
-# сделать описание принципов и деталей межобъектного взаимодействия
(об ограничениях на размер сообщений, очередь сообщений, приоритеты и т.п.)
-# попытаться сделать работу с сервисами более универсальной
(что то типа "UniSetTypes::ObjectId conf->getService(const string name)" )
-# откорректировать и дописать "общее описание" библиотеки
-# сделать тип в UniSetObject::getType string-ом
(для универсальности и простоты будущих расширений)
-# переписать тестовые примеры, под текущую ситуацию.
-# в будущем попытаться отказаться от ObjectId и перейти на строки (это надо ещё обдумать)
-# в InfoServer-е по routeList-у сообщения пересылаются, только если они локальные.
Надо переделать механизм, чтобы можно было отделять тех кому пересылать все сообщения,
от тех кому пересылать только локальные....
-# Для IOController-ов разработать спец. интерфейс для работы с датчиками (сохранение, получение состояния и т.п.)
Для того, чтобы можно было использовать разные способы хранения (БД, STL-контейнеры, файлы и т.п.). Т.к. сейчас
жёсткая реализация на STL-контейнерах.
-# дописать Mutex как надо (или перейти на omni_mutex-ы) . Сделать RWMutex и RMutex.
-# стартовые скрипты для локальной отладки (откорректировать старые)
-# управление очередью сообщений, очистка по фильтру и т.п. (может перейти на несколько очередей по приоритетам)
-# У NotifyController-а две функции с название calibrate (надо переименовать)
-# Сделать свойство tick у процессов обмена по Modbus, чтобы можно было с разной периодичностью опрашивать разные регистры
*/
......@@ -11,59 +11,59 @@ using namespace uniset::extensions;
// -----------------------------------------------------------------------------
int main( int argc, const char** argv )
{
// std::ios::sync_with_stdio(false);
// std::ios::sync_with_stdio(false);
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 << endl;
BackendOpenTSDB::help_print(argc, argv);
return 0;
}
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 << endl;
BackendOpenTSDB::help_print(argc, argv);
return 0;
}
try
{
auto conf = uniset_init( argc, argv );
try
{
auto conf = uniset_init( argc, argv );
ObjectId shmID = DefaultObjectId;
string sID = conf->getArgParam("--smemory-id");
ObjectId shmID = DefaultObjectId;
string sID = conf->getArgParam("--smemory-id");
if( !sID.empty() )
shmID = conf->getControllerID(sID);
else
shmID = getSharedMemoryID();
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;
}
if( shmID == DefaultObjectId )
{
cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
return 1;
}
auto db = BackendOpenTSDB::init_opendtsdb(argc, argv, shmID);
auto db = BackendOpenTSDB::init_opendtsdb(argc, argv, shmID);
if( !db )
{
cerr << "(opendtsdb): init failed..." << endl;
return 1;
}
if( !db )
{
cerr << "(opendtsdb): init failed..." << endl;
return 1;
}
auto act = UniSetActivator::Instance();
act->add(db);
auto act = UniSetActivator::Instance();
act->add(db);
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
act->run(false);
return 0;
}
catch( uniset::Exception& ex )
{
cerr << "(opendtsdb): " << ex << std::endl;
}
catch(...)
{
cerr << "(opendtsdb): catch ..." << std::endl;
}
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
act->run(false);
return 0;
}
catch( uniset::Exception& ex )
{
cerr << "(opendtsdb): " << ex << std::endl;
}
catch(...)
{
cerr << "(opendtsdb): catch ..." << std::endl;
}
return 1;
return 1;
}
......@@ -26,196 +26,196 @@ using namespace uniset;
// -----------------------------------------------------------------------------------------
MySQLInterface::MySQLInterface():
lastQ(""),
connected(false)
lastQ(""),
connected(false)
{
mysql = new MYSQL();
mysql_init(mysql);
// mysql_options(mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
mysql_options(mysql, MYSQL_OPT_COMPRESS, 0);
mysql = new MYSQL();
mysql_init(mysql);
// mysql_options(mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
mysql_options(mysql, MYSQL_OPT_COMPRESS, 0);
}
MySQLInterface::~MySQLInterface()
{
try
{
close();
}
catch( ... ) // пропускаем все необработанные исключения, если требуется обработать нужно вызывать close() до деструктора
{
cerr << "MySQLInterface::~MySQLInterface(): an error occured while closing connection!" << endl;
}
try
{
close();
}
catch( ... ) // пропускаем все необработанные исключения, если требуется обработать нужно вызывать close() до деструктора
{
cerr << "MySQLInterface::~MySQLInterface(): an error occured while closing connection!" << endl;
}
delete mysql;
delete mysql;
}
// -----------------------------------------------------------------------------------------
bool MySQLInterface::nconnect(const string& host, const string& user, const string& pswd, const string& dbname, unsigned int port )
{
if( !mysql_real_connect(mysql, host.c_str(), user.c_str(), pswd.c_str(), dbname.c_str(), port, NULL, 0) )
{
cout << error() << endl;
mysql_close(mysql);
connected = false;
return false;
}
if( !mysql_real_connect(mysql, host.c_str(), user.c_str(), pswd.c_str(), dbname.c_str(), port, NULL, 0) )
{
cout << error() << endl;
mysql_close(mysql);
connected = false;
return false;
}
connected = true;
return true;
connected = true;
return true;
}
// -----------------------------------------------------------------------------------------
bool MySQLInterface::close()
{
mysql_close(mysql);
return true;
mysql_close(mysql);
return true;
}
// -----------------------------------------------------------------------------------------
bool MySQLInterface::insert( const string& q )
{
if( !mysql )
return false;
if( !mysql )
return false;
if( mysql_query(mysql, q.c_str()) )
return false;
if( mysql_query(mysql, q.c_str()) )
return false;
return true;
return true;
}
// -----------------------------------------------------------------------------------------
DBResult MySQLInterface::query( const std::string& q )
{
if( !mysql )
return DBResult();
if( !mysql )
return DBResult();
if( mysql_query(mysql, q.c_str()) )
{
cerr << error() << endl;
return DBResult();
}
if( mysql_query(mysql, q.c_str()) )
{
cerr << error() << endl;
return DBResult();
}
lastQ = q;
MYSQL_RES* res = mysql_store_result(mysql); // _use_result - некорректно работает с _num_rows
lastQ = q;
MYSQL_RES* res = mysql_store_result(mysql); // _use_result - некорректно работает с _num_rows
if( !res || mysql_num_rows(res) == 0 )
return DBResult();
if( !res || mysql_num_rows(res) == 0 )
return DBResult();
return makeResult(res, true);
return makeResult(res, true);
}
// -----------------------------------------------------------------------------------------
bool MySQLInterface::query_ok( const string& q )
{
if( !mysql )
return false;
if( !mysql )
return false;
if( mysql_query(mysql, q.c_str()) )
return false;
if( mysql_query(mysql, q.c_str()) )
return false;
lastQ = q;
MYSQL_RES* res = mysql_store_result(mysql); // _use_result - некорректно работает с _num_rows
lastQ = q;
MYSQL_RES* res = mysql_store_result(mysql); // _use_result - некорректно работает с _num_rows
if( !res || mysql_num_rows(res) == 0 )
{
if( res )
mysql_free_result(res);
if( !res || mysql_num_rows(res) == 0 )
{
if( res )
mysql_free_result(res);
return false;
}
return false;
}
mysql_free_result(res);
return true;
mysql_free_result(res);
return true;
}
// -----------------------------------------------------------------------------------------
const string MySQLInterface::error()
{
return mysql_error(mysql);
return mysql_error(mysql);
}
// -----------------------------------------------------------------------------------------
const string MySQLInterface::lastQuery()
{
return lastQ;
return lastQ;
}
// -----------------------------------------------------------------------------------------
double MySQLInterface::insert_id()
{
if( !mysql )
return 0;
if( !mysql )
return 0;
return mysql_insert_id(mysql);
return mysql_insert_id(mysql);
}
// -----------------------------------------------------------------------------------------
const char* MySQLInterface::gethostinfo() const
{
return mysql_get_host_info(mysql);
return mysql_get_host_info(mysql);
}
// -----------------------------------------------------------------------------------------
bool MySQLInterface::ping() const
{
if( !mysql || !connected )
return false;
if( !mysql || !connected )
return false;
// внимание mysql_ping возвращает 0
// если всё хорошо.... (поэтому мы инвертируем)
return !mysql_ping(mysql);
// внимание mysql_ping возвращает 0
// если всё хорошо.... (поэтому мы инвертируем)
return !mysql_ping(mysql);
}
// -----------------------------------------------------------------------------------------
bool MySQLInterface::isConnection() const
{
return ping(); //!mysql;
return ping(); //!mysql;
}
// -----------------------------------------------------------------------------------------
string MySQLInterface::addslashes( const string& str )
{
ostringstream tmp;
ostringstream tmp;
for( unsigned int i = 0; i < str.size(); i++ )
{
// if( !strcmp(str[i],'\'') )
if( str[i] == '\'' )
tmp << "\\";
for( unsigned int i = 0; i < str.size(); i++ )
{
// if( !strcmp(str[i],'\'') )
if( str[i] == '\'' )
tmp << "\\";
tmp << str[i];
}
tmp << str[i];
}
return tmp.str();
return tmp.str();
}
// -----------------------------------------------------------------------------------------
DBResult MySQLInterface::makeResult( MYSQL_RES* myres, bool finalize )
{
DBResult result;
DBResult result;
if( !myres )
{
if( finalize )
mysql_free_result(myres);
if( !myres )
{
if( finalize )
mysql_free_result(myres);
return result;
}
return result;
}
MYSQL_ROW mysql_row;
unsigned int nfields = mysql_num_fields(myres);
MYSQL_ROW mysql_row;
unsigned int nfields = mysql_num_fields(myres);
while( (mysql_row = mysql_fetch_row(myres)) )
{
DBResult::COL c;
while( (mysql_row = mysql_fetch_row(myres)) )
{
DBResult::COL c;
for( unsigned int i = 0; i < nfields; i++ )
{
MYSQL_FIELD* field_info = mysql_fetch_field_direct(myres, i);
result.setColName( i, std::string(field_info->name) );
for( unsigned int i = 0; i < nfields; i++ )
{
MYSQL_FIELD* field_info = mysql_fetch_field_direct(myres, i);
result.setColName( i, std::string(field_info->name) );
c.emplace_back( (mysql_row[i] != 0 ? string(mysql_row[i]) : "") );
}
c.emplace_back( (mysql_row[i] != 0 ? string(mysql_row[i]) : "") );
}
result.row().emplace_back(c);
}
result.row().emplace_back(c);
}
if( finalize )
mysql_free_result(myres);
if( finalize )
mysql_free_result(myres);
return result;
return result;
}
// -----------------------------------------------------------------------------------------
extern "C" std::shared_ptr<DBInterface> create_mysqlinterface()
{
return std::shared_ptr<DBInterface>(new MySQLInterface(), DBInterfaceDeleter());
return std::shared_ptr<DBInterface>(new MySQLInterface(), DBInterfaceDeleter());
}
// -----------------------------------------------------------------------------------------
......@@ -32,57 +32,57 @@
// -------------------------------------------------------------------------
namespace uniset
{
// ----------------------------------------------------------------------------
// no thread safety
class MySQLInterface:
public DBNetInterface
{
public:
// ----------------------------------------------------------------------------
// no thread safety
class MySQLInterface:
public DBNetInterface
{
public:
MySQLInterface();
~MySQLInterface();
MySQLInterface();
~MySQLInterface();
// DBResult listFields( const std::string& table, const std::string& wild );
// DBResult listFields( const std::string& table, const std::string& wild );
virtual bool nconnect( const std::string& host, const std::string& user, const std::string& pswd,
const std::string& dbname, unsigned int port = 0 ) override;
virtual bool close() override;
virtual bool nconnect( const std::string& host, const std::string& user, const std::string& pswd,
const std::string& dbname, unsigned int port = 0 ) override;
virtual bool close() override;
bool query_ok( const std::string& q );
bool query_ok( const std::string& q );
// \param finalize - освободить буфер после запроса
virtual DBResult query( const std::string& q ) override;
// \param finalize - освободить буфер после запроса
virtual DBResult query( const std::string& q ) override;
virtual const std::string lastQuery() override;
virtual bool insert( const std::string& q ) override;
virtual const std::string lastQuery() override;
virtual bool insert( const std::string& q ) override;
std::string addslashes(const std::string& str);
std::string addslashes(const std::string& str);
/*!
проверка связи с БД.
в случае отсутствия попытка восстановить...
*/
virtual bool ping() const override;
/*!
проверка связи с БД.
в случае отсутствия попытка восстановить...
*/
virtual bool ping() const override;
/*! связь с БД установлена (была) */
virtual bool isConnection() const override;
/*! связь с БД установлена (была) */
virtual bool isConnection() const override;
virtual double insert_id() override;
virtual double insert_id() override;
virtual const std::string error() override;
virtual const std::string error() override;
// *******************
const char* gethostinfo() const;
protected:
// *******************
const char* gethostinfo() const;
protected:
private:
private:
DBResult makeResult( MYSQL_RES* r, bool finalize = true );
MYSQL* mysql;
std::string lastQ;
bool connected;
};
// ----------------------------------------------------------------------------------
DBResult makeResult( MYSQL_RES* r, bool finalize = true );
MYSQL* mysql;
std::string lastQ;
bool connected;
};
// ----------------------------------------------------------------------------------
} // end of namespace uniset
// ----------------------------------------------------------------------------------
#endif
......@@ -8,33 +8,33 @@ using namespace std;
// --------------------------------------------------------------------------
int main(int argc, char** argv)
{
// std::ios::sync_with_stdio(false);
// std::ios::sync_with_stdio(false);
try
{
if( argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) )
{
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
DBServer_MySQL::help_print(argc, argv);
return 0;
}
try
{
if( argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) )
{
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
DBServer_MySQL::help_print(argc, argv);
return 0;
}
auto conf = uniset_init(argc, argv, "configure.xml");
auto conf = uniset_init(argc, argv, "configure.xml");
auto db = DBServer_MySQL::init_dbserver(argc, argv);
auto db = DBServer_MySQL::init_dbserver(argc, argv);
auto act = UniSetActivator::Instance();
act->add(db);
act->run(false);
}
catch( const std::exception& ex )
{
cerr << "(DBServer::main): " << ex.what() << endl;
}
catch(...)
{
cerr << "(DBServer::main): catch ..." << endl;
}
auto act = UniSetActivator::Instance();
act->add(db);
act->run(false);
}
catch( const std::exception& ex )
{
cerr << "(DBServer::main): " << ex.what() << endl;
}
catch(...)
{
cerr << "(DBServer::main): catch ..." << endl;
}
return 0;
return 0;
}
......@@ -8,67 +8,67 @@ using namespace std;
// --------------------------------------------------------------------------
int main(int argc, char** argv)
{
std::string dbname("test-db");
std::string host("localhost");
std::string table("main_history");
std::string dbname("test-db");
std::string host("localhost");
std::string table("main_history");
if( argc > 1 )
dbname = string(argv[1]);
if( argc > 1 )
dbname = string(argv[1]);
if( argc > 2 )
host = string(argv[2]);
if( argc > 2 )
host = string(argv[2]);
if( argc > 3 )
table = string(argv[3]);
if( argc > 3 )
table = string(argv[3]);
try
{
MySQLInterface db;
try
{
MySQLInterface db;
if( !db.nconnect(host, "dbadmin", "dbadmin", dbname) )
{
cerr << "db connect error: " << db.error() << endl;
return 1;
}
if( !db.nconnect(host, "dbadmin", "dbadmin", dbname) )
{
cerr << "db connect error: " << db.error() << endl;
return 1;
}
stringstream q;
q << "SELECT * from " << table;
stringstream q;
q << "SELECT * from " << table;
DBResult r = db.query(q.str());
DBResult r = db.query(q.str());
if( !r )
{
cerr << "db connect error: " << db.error() << endl;
return 1;
}
if( !r )
{
cerr << "db connect error: " << db.error() << endl;
return 1;
}
for( DBResult::iterator it = r.begin(); it != r.end(); it++ )
{
cout << "ROW: ";
// DBResult::COL col(*it);
// for( DBResult::COL::iterator cit = col.begin(); cit != col.end(); cit++ )
// cout << DBResult::as_string(cit) << "(" << DBResult::as_double(cit) << ") | ";
// cout << endl;
for( DBResult::iterator it = r.begin(); it != r.end(); it++ )
{
cout << "ROW: ";
// DBResult::COL col(*it);
// for( DBResult::COL::iterator cit = col.begin(); cit != col.end(); cit++ )
// cout << DBResult::as_string(cit) << "(" << DBResult::as_double(cit) << ") | ";
// cout << endl;
for( DBResult::COL::iterator cit = it->begin(); cit != it->end(); cit++ )
cout << DBResult::as_string(cit) << "(" << DBResult::as_double(cit) << ") | ";
for( DBResult::COL::iterator cit = it->begin(); cit != it->end(); cit++ )
cout << DBResult::as_string(cit) << "(" << DBResult::as_double(cit) << ") | ";
cout << endl;
cout << endl;
// cout << "ID: " << r.as_string(it, "id") << endl;
cout << "ID: " << it.as_string("id") << endl;
}
// cout << "ID: " << r.as_string(it, "id") << endl;
cout << "ID: " << it.as_string("id") << endl;
}
db.close();
}
catch( const uniset::Exception& ex )
{
cerr << "(test): " << ex << endl;
}
catch( const std::exception& ex )
{
cerr << "(test): " << ex.what() << endl;
}
db.close();
}
catch( const uniset::Exception& ex )
{
cerr << "(test): " << ex << endl;
}
catch( const std::exception& ex )
{
cerr << "(test): " << ex.what() << endl;
}
return 0;
return 0;
}
......@@ -28,55 +28,55 @@
// -------------------------------------------------------------------------
namespace uniset
{
// ----------------------------------------------------------------------------
// No thread safety!
class PostgreSQLInterface:
public DBNetInterface
{
public:
// ----------------------------------------------------------------------------
// No thread safety!
class PostgreSQLInterface:
public DBNetInterface
{
public:
PostgreSQLInterface();
~PostgreSQLInterface();
PostgreSQLInterface();
~PostgreSQLInterface();
virtual bool nconnect( const std::string& host, const std::string& user,
const std::string& pswd, const std::string& dbname,
unsigned int port = 5432) override;
virtual bool close() override;
virtual bool isConnection() const override;
virtual bool ping() const override;
virtual bool nconnect( const std::string& host, const std::string& user,
const std::string& pswd, const std::string& dbname,
unsigned int port = 5432) override;
virtual bool close() override;
virtual bool isConnection() const override;
virtual bool ping() const override;
virtual DBResult query( const std::string& q ) override;
virtual void cancel_query() override;
virtual const std::string lastQuery() override;
virtual DBResult query( const std::string& q ) override;
virtual void cancel_query() override;
virtual const std::string lastQuery() override;
virtual bool insert( const std::string& q ) override;
bool insertAndSaveRowid( const std::string& q );
virtual double insert_id() override;
void save_inserted_id( const pqxx::result& res );
virtual bool insert( const std::string& q ) override;
bool insertAndSaveRowid( const std::string& q );
virtual double insert_id() override;
void save_inserted_id( const pqxx::result& res );
typedef std::list<std::string> Record;
typedef std::vector<Record> Data;
typedef std::list<std::string> Record;
typedef std::vector<Record> Data;
// fast insert: Use COPY..from SDTIN..
bool copy( const std::string& tblname, const std::vector<std::string>& cols, const Data& data );
// fast insert: Use COPY..from SDTIN..
bool copy( const std::string& tblname, const std::vector<std::string>& cols, const Data& data );
virtual const std::string error() override;
virtual const std::string error() override;
bool reconnect(const std::string& host, const std::string& user,
const std::string& pswd, const std::string& dbname,
unsigned int port = 5432);
bool reconnect(const std::string& host, const std::string& user,
const std::string& pswd, const std::string& dbname,
unsigned int port = 5432);
protected:
protected:
private:
private:
DBResult makeResult( const pqxx::result& res );
std::unique_ptr<pqxx::connection> db;
std::string lastQ;
std::string lastE;
double last_inserted_id;
};
// ----------------------------------------------------------------------------------
DBResult makeResult( const pqxx::result& res );
std::unique_ptr<pqxx::connection> db;
std::string lastQ;
std::string lastE;
double last_inserted_id;
};
// ----------------------------------------------------------------------------------
} // end of namespace uniset
// ----------------------------------------------------------------------------
#endif
......
......@@ -8,36 +8,36 @@ using namespace std;
// --------------------------------------------------------------------------
int main(int argc, char** argv)
{
// std::ios::sync_with_stdio(false);
// std::ios::sync_with_stdio(false);
try
{
if( argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) )
{
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
DBServer_PostgreSQL::help_print(argc, argv);
return 0;
}
try
{
if( argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) )
{
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
DBServer_PostgreSQL::help_print(argc, argv);
return 0;
}
auto conf = uniset_init(argc, argv);
auto conf = uniset_init(argc, argv);
auto dbs = DBServer_PostgreSQL::init_dbserver(argc, argv);
auto act = UniSetActivator::Instance();
act->add(dbs);
act->run(false);
}
catch( const uniset::Exception& ex )
{
cerr << "(DBServer_PosgreSQL::main): " << ex << endl;
}
catch( std::exception& ex )
{
cerr << "(DBServer_PosgreSQL::main): " << ex.what() << endl;
}
catch(...)
{
cerr << "(DBServer_PosgreSQL::main): catch ..." << endl;
}
auto dbs = DBServer_PostgreSQL::init_dbserver(argc, argv);
auto act = UniSetActivator::Instance();
act->add(dbs);
act->run(false);
}
catch( const uniset::Exception& ex )
{
cerr << "(DBServer_PosgreSQL::main): " << ex << endl;
}
catch( std::exception& ex )
{
cerr << "(DBServer_PosgreSQL::main): " << ex.what() << endl;
}
catch(...)
{
cerr << "(DBServer_PosgreSQL::main): catch ..." << endl;
}
return 0;
return 0;
}
......@@ -8,111 +8,111 @@ using namespace std;
// --------------------------------------------------------------------------
int main(int argc, char** argv)
{
std::string dbname("test-db");
if( argc > 1 )
dbname = string(argv[1]);
size_t ver = 1;
if( argc > 2 )
ver = atoi(argv[2]);
size_t num = 10000;
if( argc > 3 )
num = atoi(argv[3]);
try
{
PostgreSQLInterface db;
cout << "connect to '" << dbname << "'..." << endl;
if( !db.nconnect("localhost", "dbadmin", "dbadmin", dbname) )
{
cerr << "[FAILED] connect error: " << db.error() << endl;
db.close();
return 1;
}
cout << "connect to '" << dbname << "' [OK]" << endl;
stringstream q;
if( ver == 1 )
{
for( size_t i = 0; i < num; i++ )
{
q << "INSERT INTO main_history(date,time,time_usec,sensor_id,value,node)"
<< " VALUES(now(),now(),0,7,1,3000);";
}
}
else if( ver == 2 )
{
q << "INSERT INTO main_history(date,time,time_usec,sensor_id,value,node) VALUES";
for( size_t i = 0; i < num; i++ )
{
q << "(now(),now(),0,7,1,3000),";
}
q << "(now(),now(),0,7,1,3000);";
}
std::chrono::time_point<std::chrono::system_clock> start, end;
if( ver == 3 )
{
std::vector<std::string> cols = { "date", "time", "time_usec", "sensor_id", "value", "node" };
PostgreSQLInterface::Data data;
for( size_t i = 0; i < num; i++ )
{
PostgreSQLInterface::Record d = { "now()", "now()", "0", "7", "1", "3000" };
data.push_back(std::move(d));
}
start = std::chrono::system_clock::now();
if( !db.copy("main_history", cols, data) )
{
cerr << "query error: " << db.error() << endl;
db.close();
return 1;
}
}
else
{
start = std::chrono::system_clock::now();
if( !db.insert( std::move(q.str())) )
{
cerr << "query error: " << db.error() << endl;
db.close();
return 1;
}
}
end = std::chrono::system_clock::now();
int elapsed_seconds = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cerr << "INSERT " << num << " records elasped time: " << elapsed_seconds << " ms\n";
db.close();
}
catch( const uniset::Exception& ex )
{
cerr << "(test): " << ex << endl;
}
catch( std::exception& ex )
{
cerr << "(test): " << ex.what() << endl;
}
catch(...)
{
cerr << "(test): catch ..." << endl;
}
return 0;
std::string dbname("test-db");
if( argc > 1 )
dbname = string(argv[1]);
size_t ver = 1;
if( argc > 2 )
ver = atoi(argv[2]);
size_t num = 10000;
if( argc > 3 )
num = atoi(argv[3]);
try
{
PostgreSQLInterface db;
cout << "connect to '" << dbname << "'..." << endl;
if( !db.nconnect("localhost", "dbadmin", "dbadmin", dbname) )
{
cerr << "[FAILED] connect error: " << db.error() << endl;
db.close();
return 1;
}
cout << "connect to '" << dbname << "' [OK]" << endl;
stringstream q;
if( ver == 1 )
{
for( size_t i = 0; i < num; i++ )
{
q << "INSERT INTO main_history(date,time,time_usec,sensor_id,value,node)"
<< " VALUES(now(),now(),0,7,1,3000);";
}
}
else if( ver == 2 )
{
q << "INSERT INTO main_history(date,time,time_usec,sensor_id,value,node) VALUES";
for( size_t i = 0; i < num; i++ )
{
q << "(now(),now(),0,7,1,3000),";
}
q << "(now(),now(),0,7,1,3000);";
}
std::chrono::time_point<std::chrono::system_clock> start, end;
if( ver == 3 )
{
std::vector<std::string> cols = { "date", "time", "time_usec", "sensor_id", "value", "node" };
PostgreSQLInterface::Data data;
for( size_t i = 0; i < num; i++ )
{
PostgreSQLInterface::Record d = { "now()", "now()", "0", "7", "1", "3000" };
data.push_back(std::move(d));
}
start = std::chrono::system_clock::now();
if( !db.copy("main_history", cols, data) )
{
cerr << "query error: " << db.error() << endl;
db.close();
return 1;
}
}
else
{
start = std::chrono::system_clock::now();
if( !db.insert( std::move(q.str())) )
{
cerr << "query error: " << db.error() << endl;
db.close();
return 1;
}
}
end = std::chrono::system_clock::now();
int elapsed_seconds = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cerr << "INSERT " << num << " records elasped time: " << elapsed_seconds << " ms\n";
db.close();
}
catch( const uniset::Exception& ex )
{
cerr << "(test): " << ex << endl;
}
catch( std::exception& ex )
{
cerr << "(test): " << ex.what() << endl;
}
catch(...)
{
cerr << "(test): catch ..." << endl;
}
return 0;
}
......@@ -31,115 +31,115 @@
// -------------------------------------------------------------------------
namespace uniset
{
// ----------------------------------------------------------------------------
/*! \page SQLiteIntarface Интерфейс к SQLite
Пример использования:
\code
try
{
SQLiteInterface db;
if( !db.connect("test.db") )
{
cerr << "db connect error: " << db.error() << endl;
return 1;
}
stringstream q;
q << "SELECT * from main_history";
DBResult r = db.query(q.str());
if( !r )
{
cerr << "db connect error: " << db.error() << endl;
return 1;
}
for( DBResult::iterator it=r.begin(); it!=r.end(); it++ )
{
cout << "ROW: ";
DBResult::COL col(*it);
for( DBResult::COL::iterator cit = it->begin(); cit!=it->end(); cit++ )
cout << DBResult::as_string(cit) << "(" << DBResult::as_double(cit) << ") | ";
cout << endl;
}
db.close();
}
catch(Exception& ex)
{
cerr << "(test): " << ex << endl;
}
catch(...)
{
cerr << "(test): catch ..." << endl;
}
\endcode
*/
// ----------------------------------------------------------------------------
// Памятка:
// Включение режима для журнала - "вести в памяти" (чтобы поберечь CompactFlash)
// PRAGMA journal_mode = MEMORY
// При этом конечно есть риск потерять данные при выключении..
// ----------------------------------------------------------------------------
class SQLiteInterface:
public DBInterface
{
public:
SQLiteInterface();
~SQLiteInterface();
virtual bool connect( const std::string& param ) override;
bool connect(const std::string& dbfile, bool create, int extra_sqlite_flags = 0 );
virtual bool close() override;
virtual bool isConnection() const override;
virtual bool ping() const override;
void setOperationTimeout( timeout_t msec );
inline timeout_t getOperationTimeout()
{
return opTimeout;
}
inline void setOperationCheckPause( timeout_t msec )
{
opCheckPause = msec;
}
inline timeout_t getOperationCheckPause()
{
return opCheckPause;
}
virtual DBResult query( const std::string& q ) override;
virtual const std::string lastQuery() override;
bool lastQueryOK() const;
virtual bool insert( const std::string& q ) override;
virtual double insert_id() override;
virtual const std::string error() override;
protected:
bool wait( sqlite3_stmt* stmt, int result );
static bool checkResult( int rc );
private:
DBResult makeResult( sqlite3_stmt* s, bool finalize = true );
sqlite3* db;
// sqlite3_stmt* curStmt;
std::string lastQ;
std::string lastE;
bool queryok; // успешность текущего запроса
bool connected;
timeout_t opTimeout;
timeout_t opCheckPause;
};
// ----------------------------------------------------------------------------------
// ----------------------------------------------------------------------------
/*! \page SQLiteIntarface Интерфейс к SQLite
Пример использования:
\code
try
{
SQLiteInterface db;
if( !db.connect("test.db") )
{
cerr << "db connect error: " << db.error() << endl;
return 1;
}
stringstream q;
q << "SELECT * from main_history";
DBResult r = db.query(q.str());
if( !r )
{
cerr << "db connect error: " << db.error() << endl;
return 1;
}
for( DBResult::iterator it=r.begin(); it!=r.end(); it++ )
{
cout << "ROW: ";
DBResult::COL col(*it);
for( DBResult::COL::iterator cit = it->begin(); cit!=it->end(); cit++ )
cout << DBResult::as_string(cit) << "(" << DBResult::as_double(cit) << ") | ";
cout << endl;
}
db.close();
}
catch(Exception& ex)
{
cerr << "(test): " << ex << endl;
}
catch(...)
{
cerr << "(test): catch ..." << endl;
}
\endcode
*/
// ----------------------------------------------------------------------------
// Памятка:
// Включение режима для журнала - "вести в памяти" (чтобы поберечь CompactFlash)
// PRAGMA journal_mode = MEMORY
// При этом конечно есть риск потерять данные при выключении..
// ----------------------------------------------------------------------------
class SQLiteInterface:
public DBInterface
{
public:
SQLiteInterface();
~SQLiteInterface();
virtual bool connect( const std::string& param ) override;
bool connect(const std::string& dbfile, bool create, int extra_sqlite_flags = 0 );
virtual bool close() override;
virtual bool isConnection() const override;
virtual bool ping() const override;
void setOperationTimeout( timeout_t msec );
inline timeout_t getOperationTimeout()
{
return opTimeout;
}
inline void setOperationCheckPause( timeout_t msec )
{
opCheckPause = msec;
}
inline timeout_t getOperationCheckPause()
{
return opCheckPause;
}
virtual DBResult query( const std::string& q ) override;
virtual const std::string lastQuery() override;
bool lastQueryOK() const;
virtual bool insert( const std::string& q ) override;
virtual double insert_id() override;
virtual const std::string error() override;
protected:
bool wait( sqlite3_stmt* stmt, int result );
static bool checkResult( int rc );
private:
DBResult makeResult( sqlite3_stmt* s, bool finalize = true );
sqlite3* db;
// sqlite3_stmt* curStmt;
std::string lastQ;
std::string lastE;
bool queryok; // успешность текущего запроса
bool connected;
timeout_t opTimeout;
timeout_t opCheckPause;
};
// ----------------------------------------------------------------------------------
} // end of namespace uniset
// ----------------------------------------------------------------------------
#endif
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
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