Commit f032f35d authored by Pavel Vainerman's avatar Pavel Vainerman

backported to p8 as 2.6-alt11.M80P.12 (with rpmbph script)

parents 14146423 6e7ef1dc
......@@ -33,7 +33,7 @@ before_script:
# due broken comedi
- export CXXFLAGS="$CXXFLAGS -Wl,--unresolved-symbols=ignore-in-shared-libs"
- autoreconf -fiv
- ./configure --enable-tests --enable-mysql --enable-sqlite --enable-rrd --enable-io --enable-logicproc --disable-python --disable-mqtt --disable-pgsql --disable-api --disable-pkgchecklibev
- ./configure --enable-tests --enable-mysql --enable-sqlite --enable-rrd --enable-io --enable-logicproc --disable-python --disable-mqtt --disable-pgsql --disable-api --disable-pkgchecklibev --disable-netdata
script:
- if [ ${COVERITY_SCAN_BRANCH} != 1 ]; then make ; fi
......
......@@ -52,20 +52,13 @@ LogServer:
- подумать насчёт буфера для хранения последних n-сообщений (с возможностью вытащить через REST API)
HTTP API:
- запрос списка заказчиков по конкретным датчикам
- запрос о том, кто последний сохранил указанный датчик
- список объектов возвращать с их типом (чтобы можно было SM вычислять)
= Сделать возможность настраивать параметры httpserver-а из командной строки (количество потоков и т.п.)
- Сделать возможность настраивать параметры httpserver-а из командной строки (количество потоков и т.п.)
- ТЕСТЫ (как вариант поизучать про тестовые фреймворки на питоне (pytest?)
- /sensors/XXX?config=name,textname,... - запрос полей (из configure.xml)
- /conf/objects?prop1,prop2,prop3,.. - props from condigure.xml
- /conf/nodes?prop1,prop2,prop3,.. - props from condigure.xml
- /conf/controlers?..
- /conf/services?...
- /conf/...
Version 2.5
============
- Запрос у процесса обмена (MBSlave,MBxxMaster,UNet и т.п.) получение списка опрашиваемых датчиков
(датчиков с которыми ведётся работа данным процессом обмена)
- smonit запись значений в файл (csv?,sqlite?,gnuplot)
- python: gui sensor monitor
......@@ -108,11 +101,12 @@ DB: Сделать регулируемый буфер на INSERT-ы БД, чт
-----
- ведение статистики по типам сообщений в каждом объекте (и в SM). Чтобы увидеть где происходит потеря пакетов (если происходит).
(т.е. идея в том, что сколько "успешно" послала SM столько должно придти и быть обработано (разные счётчики) в объекте)
- NoSQL база (в памяти) как буфер (держит интенсивную запись) перед "не спешной" записью в реляционную (MySQL,Postgre и т.п.)
==================
Но тогда стоит вводить и namespace uniset
=================
lock-free: mentomic
version 3
......@@ -133,5 +127,3 @@ UResolver (или ObjectRepository) позволяющего манипулир
- Перепроектировать OIndex и Configure.. Инициализироват для Configure(объектом OIndex)
- подумать возможно стоит переходить на lockfree-библиотеку libcds..(актуально для многопроцессорных систем)
- Ввести namespace uniset:: ust:: uns:: ?
......@@ -244,8 +244,9 @@ int main(int argc, char** argv)
std::string userparam = { "" };
if( checkArg(optind + 1, argc, argv) )
userparam = string(argv[optind + 1]);
// смотрим второй параметр
if( checkArg(optind, argc, argv) )
userparam = string(argv[optind]);
return oinfo(optarg, ui, userparam);
}
......@@ -253,6 +254,7 @@ int main(int argc, char** argv)
case 'a': //--apiRequest
{
// смотрим второй параметр
if( checkArg(optind, argc, argv) == 0 )
{
if( !quiet )
......@@ -338,6 +340,7 @@ int main(int argc, char** argv)
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(uniset::AdminID);
string name = ( optarg ) ? optarg : "";
return logRotate(name, ui);
}
......
......@@ -107,7 +107,7 @@ void MBSlave::sigterm( int signo )
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::readCoilStatus( ReadCoilMessage& query,
ReadCoilRetMessage& reply )
ReadCoilRetMessage& reply )
{
if( verbose )
cout << "(readCoilStatus): " << query << endl;
......@@ -136,7 +136,7 @@ ModbusRTU::mbErrCode MBSlave::readCoilStatus( ReadCoilMessage& query,
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::readInputStatus( ReadInputStatusMessage& query,
ReadInputStatusRetMessage& reply )
ReadInputStatusRetMessage& reply )
{
if( verbose )
cout << "(readInputStatus): " << query << endl;
......@@ -276,7 +276,7 @@ ModbusRTU::mbErrCode MBSlave::readOutputRegisters(
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::forceMultipleCoils( ModbusRTU::ForceCoilsMessage& query,
ModbusRTU::ForceCoilsRetMessage& reply )
ModbusRTU::ForceCoilsRetMessage& reply )
{
if( verbose )
cout << "(forceMultipleCoils): " << query << endl;
......@@ -310,7 +310,7 @@ ModbusRTU::mbErrCode MBSlave::writeOutputSingleRegister( ModbusRTU::WriteSingleO
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::forceSingleCoil( ModbusRTU::ForceSingleCoilMessage& query,
ModbusRTU::ForceSingleCoilRetMessage& reply )
ModbusRTU::ForceSingleCoilRetMessage& reply )
{
if( verbose )
cout << "(forceSingleCoil): " << query << endl;
......@@ -322,7 +322,7 @@ ModbusRTU::mbErrCode MBSlave::forceSingleCoil( ModbusRTU::ForceSingleCoilMessage
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::journalCommand( ModbusRTU::JournalCommandMessage& query,
ModbusRTU::JournalCommandRetMessage& reply )
ModbusRTU::JournalCommandRetMessage& reply )
{
if( verbose )
cout << "(journalCommand): " << query << endl;
......@@ -359,7 +359,7 @@ ModbusRTU::mbErrCode MBSlave::journalCommand( ModbusRTU::JournalCommandMessage&
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::setDateTime( ModbusRTU::SetDateTimeMessage& query,
ModbusRTU::SetDateTimeRetMessage& reply )
ModbusRTU::SetDateTimeRetMessage& reply )
{
if( verbose )
cout << "(setDateTime): " << query << endl;
......@@ -371,14 +371,14 @@ ModbusRTU::mbErrCode MBSlave::setDateTime( ModbusRTU::SetDateTimeMessage& query,
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::remoteService( ModbusRTU::RemoteServiceMessage& query,
ModbusRTU::RemoteServiceRetMessage& reply )
ModbusRTU::RemoteServiceRetMessage& reply )
{
cerr << "(remoteService): " << query << endl;
return ModbusRTU::erOperationFailed;
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::fileTransfer( ModbusRTU::FileTransferMessage& query,
ModbusRTU::FileTransferRetMessage& reply )
ModbusRTU::FileTransferRetMessage& reply )
{
if( verbose )
cout << "(fileTransfer): " << query << endl;
......@@ -459,7 +459,7 @@ ModbusRTU::mbErrCode MBSlave::fileTransfer( ModbusRTU::FileTransferMessage& quer
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::diagnostics( ModbusRTU::DiagnosticMessage& query,
ModbusRTU::DiagnosticRetMessage& reply )
ModbusRTU::DiagnosticRetMessage& reply )
{
if( verbose )
cout << "(diagnostics): " << query << endl;
......
......@@ -43,26 +43,26 @@ class MBSlave
/*! обработка 0x01 */
uniset::ModbusRTU::mbErrCode readCoilStatus( uniset::ModbusRTU::ReadCoilMessage& query,
uniset::ModbusRTU::ReadCoilRetMessage& reply );
uniset::ModbusRTU::ReadCoilRetMessage& reply );
/*! обработка 0x02 */
uniset::ModbusRTU::mbErrCode readInputStatus( uniset::ModbusRTU::ReadInputStatusMessage& query,
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
/*! обработка 0x03 */
uniset::ModbusRTU::mbErrCode readOutputRegisters( uniset::ModbusRTU::ReadOutputMessage& query,
uniset::ModbusRTU::ReadOutputRetMessage& reply );
uniset::ModbusRTU::ReadOutputRetMessage& reply );
/*! обработка 0x04 */
uniset::ModbusRTU::mbErrCode readInputRegisters( uniset::ModbusRTU::ReadInputMessage& query,
uniset::ModbusRTU::ReadInputRetMessage& reply );
uniset::ModbusRTU::ReadInputRetMessage& reply );
/*! обработка 0x05 */
uniset::ModbusRTU::mbErrCode forceSingleCoil( uniset::ModbusRTU::ForceSingleCoilMessage& query,
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
/*! обработка 0x0F */
uniset::ModbusRTU::mbErrCode forceMultipleCoils( uniset::ModbusRTU::ForceCoilsMessage& query,
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
/*! обработка 0x10 */
......@@ -75,21 +75,21 @@ class MBSlave
/*! обработка запросов на чтение ошибок */
uniset::ModbusRTU::mbErrCode journalCommand( uniset::ModbusRTU::JournalCommandMessage& query,
uniset::ModbusRTU::JournalCommandRetMessage& reply );
uniset::ModbusRTU::JournalCommandRetMessage& reply );
/*! обработка запроса на установку времени */
uniset::ModbusRTU::mbErrCode setDateTime( uniset::ModbusRTU::SetDateTimeMessage& query,
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
/*! обработка запроса удалённого сервиса */
uniset::ModbusRTU::mbErrCode remoteService( uniset::ModbusRTU::RemoteServiceMessage& query,
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
uniset::ModbusRTU::mbErrCode fileTransfer( uniset::ModbusRTU::FileTransferMessage& query,
uniset::ModbusRTU::FileTransferRetMessage& reply );
uniset::ModbusRTU::FileTransferRetMessage& reply );
uniset::ModbusRTU::mbErrCode diagnostics( uniset::ModbusRTU::DiagnosticMessage& query,
uniset::ModbusRTU::DiagnosticRetMessage& reply );
uniset::ModbusRTU::DiagnosticRetMessage& reply );
uniset::ModbusRTU::mbErrCode read4314( uniset::ModbusRTU::MEIMessageRDI& query,
uniset::ModbusRTU::MEIMessageRetRDI& reply );
......
......@@ -83,7 +83,7 @@ void MBTCPServer::sigterm( int signo )
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBTCPServer::readCoilStatus( ReadCoilMessage& query,
ReadCoilRetMessage& reply )
ReadCoilRetMessage& reply )
{
if( verbose )
cout << "(readCoilStatus): " << query << endl;
......@@ -168,7 +168,7 @@ ModbusRTU::mbErrCode MBTCPServer::readInputStatus( ReadInputStatusMessage& query
}
// -------------------------------------------------------------------------
mbErrCode MBTCPServer::readInputRegisters( ReadInputMessage& query,
ReadInputRetMessage& reply )
ReadInputRetMessage& reply )
{
if( verbose )
cout << "(readInputRegisters): " << query << endl;
......@@ -296,7 +296,7 @@ ModbusRTU::mbErrCode MBTCPServer::forceSingleCoil( ModbusRTU::ForceSingleCoilMes
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBTCPServer::journalCommand( ModbusRTU::JournalCommandMessage& query,
ModbusRTU::JournalCommandRetMessage& reply )
ModbusRTU::JournalCommandRetMessage& reply )
{
if( verbose )
cout << "(journalCommand): " << query << endl;
......@@ -333,7 +333,7 @@ ModbusRTU::mbErrCode MBTCPServer::journalCommand( ModbusRTU::JournalCommandMessa
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBTCPServer::setDateTime( ModbusRTU::SetDateTimeMessage& query,
ModbusRTU::SetDateTimeRetMessage& reply )
ModbusRTU::SetDateTimeRetMessage& reply )
{
if( verbose )
cout << "(setDateTime): " << query << endl;
......@@ -345,14 +345,14 @@ ModbusRTU::mbErrCode MBTCPServer::setDateTime( ModbusRTU::SetDateTimeMessage& qu
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBTCPServer::remoteService( ModbusRTU::RemoteServiceMessage& query,
ModbusRTU::RemoteServiceRetMessage& reply )
ModbusRTU::RemoteServiceRetMessage& reply )
{
cerr << "(remoteService): " << query << endl;
return ModbusRTU::erOperationFailed;
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBTCPServer::fileTransfer( ModbusRTU::FileTransferMessage& query,
ModbusRTU::FileTransferRetMessage& reply )
ModbusRTU::FileTransferRetMessage& reply )
{
if( verbose )
cout << "(fileTransfer): " << query << endl;
......@@ -433,7 +433,7 @@ ModbusRTU::mbErrCode MBTCPServer::fileTransfer( ModbusRTU::FileTransferMessage&
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBTCPServer::diagnostics( ModbusRTU::DiagnosticMessage& query,
ModbusRTU::DiagnosticRetMessage& reply )
ModbusRTU::DiagnosticRetMessage& reply )
{
if( query.subf == ModbusRTU::subEcho )
{
......@@ -472,7 +472,7 @@ ModbusRTU::mbErrCode MBTCPServer::diagnostics( ModbusRTU::DiagnosticMessage& que
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBTCPServer::read4314( ModbusRTU::MEIMessageRDI& query,
ModbusRTU::MEIMessageRetRDI& reply )
ModbusRTU::MEIMessageRetRDI& reply )
{
if( verbose )
cout << "(read4314): " << query << endl;
......
......@@ -39,26 +39,26 @@ class MBTCPServer
/*! обработка 0x01 */
uniset::ModbusRTU::mbErrCode readCoilStatus( uniset::ModbusRTU::ReadCoilMessage& query,
uniset::ModbusRTU::ReadCoilRetMessage& reply );
uniset::ModbusRTU::ReadCoilRetMessage& reply );
/*! обработка 0x02 */
uniset::ModbusRTU::mbErrCode readInputStatus( uniset::ModbusRTU::ReadInputStatusMessage& query,
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
/*! обработка 0x03 */
uniset::ModbusRTU::mbErrCode readOutputRegisters( uniset::ModbusRTU::ReadOutputMessage& query,
uniset::ModbusRTU::ReadOutputRetMessage& reply );
uniset::ModbusRTU::ReadOutputRetMessage& reply );
/*! обработка 0x04 */
uniset::ModbusRTU::mbErrCode readInputRegisters( uniset::ModbusRTU::ReadInputMessage& query,
uniset::ModbusRTU::ReadInputRetMessage& reply );
uniset::ModbusRTU::ReadInputRetMessage& reply );
/*! обработка 0x05 */
uniset::ModbusRTU::mbErrCode forceSingleCoil( uniset::ModbusRTU::ForceSingleCoilMessage& query,
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
/*! обработка 0x0F */
uniset::ModbusRTU::mbErrCode forceMultipleCoils( uniset::ModbusRTU::ForceCoilsMessage& query,
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
/*! обработка 0x10 */
......@@ -71,25 +71,25 @@ class MBTCPServer
uniset::ModbusRTU::mbErrCode diagnostics( uniset::ModbusRTU::DiagnosticMessage& query,
uniset::ModbusRTU::DiagnosticRetMessage& reply );
uniset::ModbusRTU::DiagnosticRetMessage& 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::JournalCommandRetMessage& reply );
/*! обработка запроса на установку времени */
uniset::ModbusRTU::mbErrCode setDateTime( uniset::ModbusRTU::SetDateTimeMessage& query,
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
/*! обработка запроса удалённого сервиса */
uniset::ModbusRTU::mbErrCode remoteService( uniset::ModbusRTU::RemoteServiceMessage& query,
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
uniset::ModbusRTU::mbErrCode fileTransfer( uniset::ModbusRTU::FileTransferMessage& query,
uniset::ModbusRTU::FileTransferRetMessage& reply );
uniset::ModbusRTU::FileTransferRetMessage& reply );
/*! интерфейс ModbusSlave для обмена по RS */
......
......@@ -250,7 +250,7 @@
std::string strval( uniset::ObjectId id, bool showLinkName=true ) const;
/*! Вывод состояния внутренних переменных */
inline std::string dumpVars(){ return std::move(vmon.pretty_str()); }
inline std::string dumpVars(){ return vmon.pretty_str(); }
// ------------------------------------------------------------
std::string help() noexcept;
......@@ -416,6 +416,8 @@
std::unordered_map&lt;const uniset::ObjectId,size_t, StatHashFn&gt; smStat; /*!&lt; количество сообщений по датчикам */
size_t processingMessageCatchCount = { 0 }; /*!&lt; количество исключений пойманных в processingMessage */
std::string ostate = { "" }; /*!&lt; состояние процесса (выводится в getInfo()) */
</xsl:if>
</xsl:template>
......@@ -476,22 +478,42 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::preSysCommand( const SystemMessage*
}
case SystemMessage::StartUp:
{
if( !logserv_host.empty() &amp;&amp; logserv_port != 0 &amp;&amp; !logserv-&gt;isRunning() )
ostate = "StartUp...";
try
{
if( !logserv_host.empty() &amp;&amp; logserv_port != 0 &amp;&amp; !logserv-&gt;isRunning() )
{
ostate = "StartUp: run log server...";
myinfo &lt;&lt; myname &lt;&lt; "(preSysCommand): run log server " &lt;&lt; logserv_host &lt;&lt; ":" &lt;&lt; logserv_port &lt;&lt; endl;
logserv-&gt;run(logserv_host, logserv_port, true);
}
}
catch( std::exception&amp; ex )
{
myinfo &lt;&lt; myname &lt;&lt; "(preSysCommand): run log server " &lt;&lt; logserv_host &lt;&lt; ":" &lt;&lt; logserv_port &lt;&lt; endl;
logserv-&gt;run(logserv_host, logserv_port, true);
mywarn &lt;&lt; myname &lt;&lt; "(preSysCommand): CAN`t run log server err: " &lt;&lt; ex.what() &lt;&lt; endl;
}
catch( ... )
{
mywarn &lt;&lt; myname &lt;&lt; "(preSysCommand): CAN`t run log server err: catch ..." &lt;&lt; endl;
}
ostate = "StartUp: wait sm ready..";
waitSM(smReadyTimeout);
ptStartUpTimeout.reset();
// т.к. для io-переменных важно соблюдать последовательность!
// сперва обновить входы..
ostate = "StartUp: update values..";
updateValues();
ostate = "StartUp: init from SM..";
initFromSM(); // потом обновить значения переменных, помеченных как инициализируемые из SM
ostate = "StartUp: update outputs..";
updateOutputs(true); // а потом уже выходы (принудительное обновление)
ostate = "StartUp: pre ask sensors..";
preAskSensors(UniversalIO::UIONotify);
ostate = "StartUp: ask sensors..";
askSensors(UniversalIO::UIONotify);
active = true;
ostate = "StartUp: [OK]";
break;
}
......@@ -514,8 +536,19 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::preSysCommand( const SystemMessage*
if( logserv &amp;&amp; !logserv_host.empty() &amp;&amp; logserv_port != 0 )
{
mylogany &lt;&lt; myname &lt;&lt; "(preSysCommand): try restart logserver.." &lt;&lt; endl;
logserv-&gt;check(true);
try
{
mylogany &lt;&lt; myname &lt;&lt; "(preSysCommand): try restart logserver.." &lt;&lt; endl;
logserv-&gt;check(true);
}
catch( std::exception&amp; ex )
{
mywarn &lt;&lt; myname &lt;&lt; "(preSysCommand): CAN`t restart log server err: " &lt;&lt; ex.what() &lt;&lt; endl;
}
catch( ... )
{
mywarn &lt;&lt; myname &lt;&lt; "(preSysCommand): CAN`t restart log server err: catch ..." &lt;&lt; endl;
}
}
}
break;
......@@ -536,6 +569,8 @@ uniset::SimpleInfo* <xsl:value-of select="$CLASSNAME"/>_SK::getInfo( const char*
ostringstream inf;
inf &lt;&lt; i->info &lt;&lt; endl;
inf &lt;&lt; "process state: " &lt;&lt; ostate &lt;&lt; endl;
if( logserv /* &amp;&amp; userparam &lt; 0 */ )
{
inf &lt;&lt; "LogServer: " &lt;&lt; logserv_host &lt;&lt; ":" &lt;&lt; logserv_port
......@@ -654,7 +689,7 @@ Poco::JSON::Object::Ptr <xsl:value-of select="$CLASSNAME"/>_SK::httpRequest( con
Poco::JSON::Object::Ptr <xsl:value-of select="$CLASSNAME"/>_SK::httpRequestLog( const Poco::URI::QueryParameters&amp; p )
{
Poco::JSON::Object::Ptr jret = new Poco::JSON::Object();
jret->set(myname,uniset::json::make_object("log", Debug::str(mylog->level())));
jret->set("log",Debug::str(mylog->level()));
return jret;
}
// -----------------------------------------------------------------------------
......@@ -801,10 +836,7 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::waitSM( int wait_msec, ObjectId _te
&lt;&lt; wait_msec &lt;&lt; " мсек";
mycrit &lt;&lt; err.str() &lt;&lt; endl;
// terminate();
// abort();
// raise(SIGTERM);
std::terminate();
std::abort();
// throw uniset::SystemError(err.str());
}
......@@ -816,10 +848,7 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::waitSM( int wait_msec, ObjectId _te
&lt;&lt; wait_msec &lt;&lt; " мсек";
mycrit &lt;&lt; err.str() &lt;&lt; endl;
// terminate();
// abort();
//raise(SIGTERM);
std::terminate();
std::abort();
// throw uniset::SystemError(err.str());
}
}
......@@ -849,7 +878,7 @@ std::string <xsl:value-of select="$CLASSNAME"/>_SK::help() noexcept
s &lt;&lt; " ****************************************************************************************** " &lt;&lt; endl;
return std::move(s.str());
return s.str();
}
// ----------------------------------------------------------------------------
</xsl:template>
......@@ -1230,9 +1259,9 @@ end_private(false)
if( smTestID == DefaultObjectId )
smTestID = getSMTestID();
activateTimeout = conf->getArgPInt("--" + argprefix + "activate-timeout", 20000);
activateTimeout = conf->getArgPInt("--" + argprefix + "activate-timeout", 90000);
int msec = conf->getArgPInt("--" + argprefix + "startup-timeout", 10000);
int msec = conf->getArgPInt("--" + argprefix + "startup-timeout", 50000);
ptStartUpTimeout.setTiming(msec);
// ===================== &lt;variables&gt; =====================
......@@ -1500,7 +1529,7 @@ std::string <xsl:value-of select="$CLASSNAME"/>_SK::dumpIO()
s &lt;&lt; std::endl;
}
return std::move(s.str());
return s.str();
}
// ----------------------------------------------------------------------------
std::string <xsl:value-of select="$CLASSNAME"/>_SK::str( uniset::ObjectId id, bool showLinkName ) const
......@@ -1511,7 +1540,7 @@ std::string <xsl:value-of select="$CLASSNAME"/>_SK::str( uniset::ObjectId id, b
{
s &lt;&lt; "<xsl:call-template name="setprefix"/><xsl:value-of select="@name"/>";
if( showLinkName ) s &lt;&lt; "(" &lt;&lt; ORepHelpers::getShortName( uniset_conf()->oind->getMapName(<xsl:value-of select="@name"/>)) &lt;&lt; ")";
return std::move(s.str());
return s.str();
}
</xsl:for-each>
return "";
......@@ -1527,7 +1556,7 @@ std::string <xsl:value-of select="$CLASSNAME"/>_SK::strval( uniset::ObjectId id
s &lt;&lt; "<xsl:call-template name="setprefix"/><xsl:value-of select="@name"/>";
if( showLinkName ) s &lt;&lt; "(" &lt;&lt; ORepHelpers::getShortName( uniset_conf()->oind->getMapName(<xsl:value-of select="@name"/>)) &lt;&lt; ")";
s &lt;&lt; "=" &lt;&lt; <xsl:call-template name="setprefix"/><xsl:value-of select="@name"/>;
return std::move(s.str());
return s.str();
}
</xsl:for-each>
return "";
......@@ -1699,10 +1728,11 @@ askPause(uniset_conf()->getPIntProp(cnode,"askPause",2000))
vmonit(smTestID);
vmonit(smReadyTimeout);
vmonit(activateTimeout);
activateTimeout = conf->getArgPInt("--" + argprefix + "activate-timeout", 20000);
activateTimeout = conf->getArgPInt("--" + argprefix + "activate-timeout", 90000);
int msec = conf->getArgPInt("--" + argprefix + "startup-timeout", 10000);
int msec = conf->getArgPInt("--" + argprefix + "startup-timeout", 60000);
ptStartUpTimeout.setTiming(msec);
}
......@@ -1868,7 +1898,7 @@ std::string <xsl:value-of select="$CLASSNAME"/>_SK::dumpIO()
s &lt;&lt; endl;
}
return std::move(s.str());
return s.str();
}
// ----------------------------------------------------------------------------
std::string <xsl:value-of select="$CLASSNAME"/>_SK::str( uniset::ObjectId id, bool showLinkName ) const
......@@ -1881,7 +1911,7 @@ std::string <xsl:value-of select="$CLASSNAME"/>_SK::str( uniset::ObjectId id, b
{
s &lt;&lt; "<xsl:call-template name="setprefix"/><xsl:value-of select="../../@name"/>";
if( showLinkName ) s &lt;&lt; "(<xsl:value-of select="../../@name"/>)";
return std::move(s.str());
return s.str();
}
</xsl:if>
</xsl:if>
......@@ -1900,7 +1930,7 @@ std::string <xsl:value-of select="$CLASSNAME"/>_SK::strval( uniset::ObjectId id,
s &lt;&lt; "<xsl:call-template name="setprefix"/><xsl:value-of select="../../@name"/>";
if( showLinkName ) s &lt;&lt; " ( <xsl:value-of select="../../@name"/> )";
s &lt;&lt; "=" &lt;&lt; <xsl:call-template name="setprefix"/><xsl:value-of select="../../@name"/>;
return std::move(s.str());
return s.str();
}
</xsl:if>
</xsl:if>
......
......@@ -18,7 +18,7 @@
Name: libuniset2
Version: 2.6
Release: alt3.M80P.4
Release: alt11.M80P.12
Summary: UniSet - library for building distributed industrial control systems
License: LGPL
......@@ -79,7 +79,7 @@ BuildRequires(pre): rpm-build-python
%endif
%if_enabled docs
BuildRequires: doxygen
BuildRequires: doxygen graphviz ImageMagick-tools
%endif
%if_enabled tests
......@@ -317,23 +317,23 @@ SharedMemoryPlus extension ('all in one') for libuniset
%build
%autoreconf
%configure %{subst_enable docs} %{subst_enable mysql} %{subst_enable sqlite} %{subst_enable pgsql} %{subst_enable python} %{subst_enable rrd} %{subst_enable io} %{subst_enable logicproc} %{subst_enable tests} %{subst_enable mqtt} %{subst_enable api}
%make
%configure %{subst_enable docs} %{subst_enable mysql} %{subst_enable sqlite} %{subst_enable pgsql} %{subst_enable python} %{subst_enable rrd} %{subst_enable io} %{subst_enable logicproc} %{subst_enable tests} %{subst_enable mqtt} %{subst_enable api} %{subst_enable netdata}
%make_build
# fix for ALTLinux build (noarch)
%if_enabled docs
cd docs/html
PNGFILES=`find ./ -name '*.png' -type f`
for F in ${PNGFILES}; do
# echo "$F"
convert ${F} -flatten +matte ${F}
done
%endif
%install
%makeinstall_std
rm -f %buildroot%_libdir/*.la
%if_enabled python
mkdir -p %buildroot%python_sitelibdir/%oname
mv -f %buildroot%python_sitelibdir/*.* %buildroot%python_sitelibdir/%oname/
%ifarch x86_64
mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
%endif
%endif
%files utils
%_bindir/%oname-admin
%_bindir/%oname-mb*
......@@ -400,7 +400,8 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
%if_enabled python
%files -n python-module-%oname
%python_sitelibdir/%oname/
%python_sitelibdir/*
%python_sitelibdir_noarch/%oname/*
%endif
%if_enabled netdata
......@@ -509,9 +510,40 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# history of current unpublished changes
%changelog
* Wed Dec 07 2016 Pavel Vainerman <pv@altlinux.ru> 2.6-alt3.M80P.4
* Mon Mar 06 2017 Pavel Vainerman <pv@altlinux.ru> 2.6-alt11.M80P.12
- backport to ALTLinux p8 (by rpmbph script)
* Mon Feb 27 2017 Pavel Vainerman <pv@altlinux.ru> 2.6-alt12
- up version
* Tue Feb 21 2017 Alexei Takaseev <taf@altlinux.org> 2.6-alt10.1
- Rebuild with poco 1.7.7
* Mon Jan 09 2017 Pavel Vainerman <pv@altlinux.ru> 2.6-alt10
- add tests for REST API (with RPC)
- python: refactoring UInterface (add UInterfaceModbus and UInterfaceUniSet)
- refactoring TCPCheck (use future)
- minor refactoring and fixes
* Fri Dec 16 2016 Pavel Vainerman <pv@altlinux.ru> 2.6-alt9
- UObject: added attempts to activate the object
* Wed Dec 14 2016 Pavel Vainerman <pv@altlinux.ru> 2.6-alt8
- SM: terminate if read dump (configuration) failed
* Tue Dec 13 2016 Pavel Vainerman <pv@altlinux.ru> 2.6-alt7
- Modbus: refactoring code and test (for 64bit)
- iobase: refactoring tests for 64bit
- TCPCheck: fixed bug (for exit thread)
- UNetUDP: minor fixes in tests
* Mon Dec 12 2016 Pavel Vainerman <pv@altlinux.ru> 2.6-alt6
- codegen: up timeout or activate
- codegen: add logs for startup
* Thu Dec 08 2016 Pavel Vainerman <pv@altlinux.ru> 2.6-alt5
- fixed bug in uniset2-admin --oinfo
* Wed Dec 07 2016 Pavel Vainerman <pv@altlinux.ru> 2.6-alt4
- new version
- getChangedTime --> getTimeChange
......
......@@ -9,7 +9,6 @@ REL=eter
MAILDOMAIN=server
[ -z "$TOPDIR" ] && TOPDIR=/var/ftp/pub/Ourside
[ -z "$GEN" ] && GEN=/var/ftp/pub/Ourside/$PLATFORM/genb.sh
PKGNAME=uniset2
SPECNAME=libuniset2.spec
......@@ -22,6 +21,7 @@ fi
PROJECT=$1
test -n "$PROJECT" || PROJECT=$PKGNAME
[ -z "$GEN" ] && GEN=/var/ftp/pub/Ourside/$PLATFORM/genb.sh
[ -a "$GEN" ] || GEN="genbasedir --create --progress --topdir=$TOPDIR $PLATFORM $PROJECT"
[ -z "$FTPDIR" ] && FTPDIR=$TOPDIR/$PLATFORM/RPMS.$PROJECT
......@@ -62,13 +62,38 @@ function cp2ftp()
# ------------------------------------------------------------------------
add_changelog_helper "- new build" $SPECNAME
# Увеличиваем подрелиз (.x+1) до сборки!
if [ -n "$BUILD_AUTOINCREMENT_SUBRELEASE" ]; then
inc_subrelease $SPECNAME
COMMIT="$(git rev-parse --verify HEAD)"
add_changelog -e "- (autobuild): commit $COMMIT" $SPECNAME
elif [ -n "$JENKINS_BUILD_AUTOINCREMENT" ]; then
rel="$(get_release $SPECNAME)"
# Смотрим номер сборки в JENKINS
if [ -n "$BUILD_NUMBER" ]; then
rel="${rel}.${JENKINS_PREFIX}${BUILD_NUMBER}"
set_release $SPECNAME $rel
else
# просто увеличиваем subrelease
inc_subrelease $SPECNAME
fi
COMMIT="$(git rev-parse --verify HEAD)"
add_changelog -e "- (jenkinsbuild): commit $COMMIT" $SPECNAME
else
# обычный build
add_changelog_helper "- new build" $SPECNAME
fi
rpmbb ${UNISET_BUILD_ADDON_OPTIONS} $SPECNAME || fatal "Can't build"
cp2ftp
rpmbs $SPECNAME
#rpmbs $SPECNAME
#send_notify
# Увеличиваем релиз и запоминаем спек после успешной сборки
......
......@@ -32,7 +32,7 @@ AC_ENABLE_SHARED(yes)
AC_ENABLE_STATIC(no)
AM_PROG_LIBTOOL
ASTYLE_OPT="-A1 -T -C -S -L -w -Y -M -f -p --mode=c --lineend=linux --align-reference=type --align-pointer=type --suffix=none --style=ansi --max-instatement-indent=50"
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"
AC_SUBST(ASTYLE_OPT)
# Checks for libraries.
......@@ -40,19 +40,17 @@ PKG_CHECK_MODULES(XML, libxml-2.0)
PKG_CHECK_MODULES(OMNI, omniORB4)
PKG_CHECK_MODULES(SIGC, sigc++-2.0)
nopkgchecklibev=false
AC_ARG_ENABLE(pkgchecklibev, AC_HELP_STRING([--disable-pkgchecklibev], [disable pkg check modules for libev]),
[ if test $enableval = yes; then nopkgchecklibev=false; else nopkgchecklibev=true; fi],[ nopkgchecklibev=false; ])
checklibev=true
PKG_CHECK_MODULES(EV, libev, [ checklibev=false; ], [ checklibev=true; ])
if test ${nopkgchecklibev} = false; then
PKG_CHECK_MODULES(EV, libev)
else
if test $checklibev = true; then
AC_CHECK_HEADER(ev++.h,,exit)
AC_SEARCH_LIBS(ev_run,ev,[],[],exit)
EV_LIBS="-lev"
EV_CFLAGS=
AC_SUBST(EV_LIBS)
AC_SUBST(EV_CFLAGS)
AC_MSG_RESULT([ok])
fi
#check rest api support
......@@ -239,10 +237,24 @@ if test ${buildpython} = true; then
AC_MSG_RESULT([enabled])
dnl Python
AM_PATH_PYTHON(,,)
PKG_CHECK_MODULES(PYTHON,python,,exit)
PKG_CHECK_MODULES(PYTHON,python-2.7,,exit)
# AC_CHECK_PROG(SWIG, swig, yes, exit)
AC_MSG_CHECKING([netdata python plugin])
netdata=true
AC_ARG_ENABLE(netdata,AC_HELP_STRING([--disable-netdata], [disable build netdata python plugin]),
[ if test $enableval = yes; then netdata=true; else netdata=false; fi],[ netdata=true; ])
if test ${netdata} = true; then
AC_MSG_RESULT([enabled])
else
AC_MSG_RESULT([disabled])
fi
AM_CONDITIONAL(HAVE_NETDATA, test ${netdata} = true)
else
AC_MSG_RESULT([disabled])
AM_CONDITIONAL(HAVE_NETDATA, false)
fi
AM_CONDITIONAL(DISABLE_PYTHON, test ${buildpython} = false)
......@@ -361,7 +373,7 @@ AM_CONDITIONAL(HAVE_TESTS, test ${buildtests} = true)
# -D_GLIBCXX_USE_NANOSLEEP - for std::this_thread::sleep_for
# -Weffc++ -Wno-unused-variable -Werror -Wctor-dtor-privacy
CXX_EXTRA_FLAGS="-Wnon-virtual-dtor -Woverloaded-virtual -Woverflow -D_GLIBCXX_USE_NANOSLEEP"
CXX_EXTRA_FLAGS="-Wnon-virtual-dtor -Woverloaded-virtual -Woverflow -D_GLIBCXX_USE_NANOSLEEP -fstack-protector"
# export
LDFLAGS="$LDFLAGS ${OMNI_LIBS} ${XML_LIBS} ${SIGC_LIBS} ${COV_LIBS} ${POCO_LIBS} ${EV_LIBS}"
......
......@@ -177,7 +177,7 @@ string MySQLInterface::addslashes( const string& str )
tmp << str[i];
}
return std::move(tmp.str());
return tmp.str();
}
// -----------------------------------------------------------------------------------------
void MySQLInterface::makeResult(DBResult& dbres, MYSQL_RES* myres, bool finalize )
......
......@@ -32,56 +32,56 @@
// -------------------------------------------------------------------------
namespace uniset
{
// ----------------------------------------------------------------------------
class MySQLInterface:
public DBNetInterface
{
public:
// ----------------------------------------------------------------------------
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:
void makeResult(DBResult& dbres, MYSQL_RES* r, bool finalize = true );
MYSQL* mysql;
std::string lastQ;
bool connected;
};
// ----------------------------------------------------------------------------------
void makeResult(DBResult& dbres, MYSQL_RES* r, bool finalize = true );
MYSQL* mysql;
std::string lastQ;
bool connected;
};
// ----------------------------------------------------------------------------------
} // end of namespace uniset
// ----------------------------------------------------------------------------------
#endif
......@@ -182,7 +182,7 @@ DBResult PostgreSQLInterface::query( const string& q )
result res( n.exec(q) );
DBResult dbres;
makeResult(dbres, res);
return std::move(dbres);
return dbres;
}
catch( const std::exception& e )
{
......
......@@ -28,49 +28,49 @@
// -------------------------------------------------------------------------
namespace uniset
{
// ----------------------------------------------------------------------------
class PostgreSQLInterface:
public DBNetInterface
{
public:
// ----------------------------------------------------------------------------
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 const std::string lastQuery() override;
virtual DBResult query( const std::string& q ) 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::list<std::string>& cols, const Data& data );
// fast insert: Use COPY..from SDTIN..
bool copy( const std::string& tblname, const std::list<std::string>& cols, const Data& data );
virtual const std::string error() override;
virtual const std::string error() override;
protected:
protected:
private:
private:
void makeResult(DBResult& dbres, const pqxx::result& res );
std::shared_ptr<pqxx::connection> db;
std::string lastQ;
std::string lastE;
double last_inserted_id;
};
// ----------------------------------------------------------------------------------
void makeResult(DBResult& dbres, const pqxx::result& res );
std::shared_ptr<pqxx::connection> db;
std::string lastQ;
std::string lastE;
double last_inserted_id;
};
// ----------------------------------------------------------------------------------
} // end of namespace uniset
// ----------------------------------------------------------------------------
#endif
......
......@@ -31,114 +31,114 @@
// -------------------------------------------------------------------------
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 );
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;
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:
void makeResult(DBResult& dbres, 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 );
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;
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:
void makeResult(DBResult& dbres, 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
......
......@@ -23,66 +23,66 @@
//--------------------------------------------------------------------------
namespace uniset
{
// -----------------------------------------------------------------------------
/*! Интерфейс для работы с в/в */
class ComediInterface
{
public:
explicit ComediInterface( const std::string& dev );
~ComediInterface();
// -----------------------------------------------------------------------------
/*! Интерфейс для работы с в/в */
class ComediInterface
{
public:
explicit ComediInterface( const std::string& dev );
~ComediInterface();
int getAnalogChannel( int subdev, int channel, int range = 0, int aref = AREF_GROUND )
throw(uniset::Exception);
int getAnalogChannel( int subdev, int channel, int range = 0, int aref = AREF_GROUND )
throw(uniset::Exception);
void setAnalogChannel( int subdev, int channel, int data, int range = 0, int aref = AREF_GROUND )
throw(uniset::Exception);
void setAnalogChannel( int subdev, int channel, int data, int range = 0, int aref = AREF_GROUND )
throw(uniset::Exception);
bool getDigitalChannel( int subdev, int channel )
throw(uniset::Exception);
bool getDigitalChannel( int subdev, int channel )
throw(uniset::Exception);
void setDigitalChannel( int subdev, int channel, bool bit )
throw(uniset::Exception);
void setDigitalChannel( int subdev, int channel, bool bit )
throw(uniset::Exception);
// Конфигурирование входов / выходов
enum ChannelType
{
DI = INSN_CONFIG_DIO_INPUT,
DO = INSN_CONFIG_DIO_OUTPUT,
AI = 100, // INSN_CONFIG_AIO_INPUT,
AO = 101 // INSN_CONFIG_AIO_OUTPUT
};
// Конфигурирование входов / выходов
enum ChannelType
{
DI = INSN_CONFIG_DIO_INPUT,
DO = INSN_CONFIG_DIO_OUTPUT,
AI = 100, // INSN_CONFIG_AIO_INPUT,
AO = 101 // INSN_CONFIG_AIO_OUTPUT
};
enum SubdevType
{
Unknown = 0,
TBI24_0 = 1,
TBI0_24 = 2,
TBI16_8 = 3,
GRAYHILL = 4
};
enum SubdevType
{
Unknown = 0,
TBI24_0 = 1,
TBI0_24 = 2,
TBI16_8 = 3,
GRAYHILL = 4
};
static std::string type2str( SubdevType t );
static SubdevType str2type( const std::string& s );
static std::string type2str( SubdevType t );
static SubdevType str2type( const std::string& s );
void configureSubdev( int subdev, SubdevType type ) throw(uniset::Exception);
void configureSubdev( int subdev, SubdevType type ) throw(uniset::Exception);
void configureChannel( int subdev, int channel, ChannelType type, int range = 0, int aref = 0 )
throw(uniset::Exception);
void configureChannel( int subdev, int channel, ChannelType type, int range = 0, int aref = 0 )
throw(uniset::Exception);
inline const std::string devname()
{
return dname;
}
inline const std::string devname()
{
return dname;
}
protected:
protected:
comedi_t* card; /*!< интерфейс для работы с картами в/в */
std::string dname;
comedi_t* card; /*!< интерфейс для работы с картами в/в */
std::string dname;
private:
};
// --------------------------------------------------------------------------
private:
};
// --------------------------------------------------------------------------
} // end of namespace uniset
// -----------------------------------------------------------------------------
#endif // ComediInterface_H_
......
......@@ -20,104 +20,104 @@
// -----------------------------------------------------------------------------
namespace uniset
{
// -------------------------------------------------------------------------
using namespace std;
// -------------------------------------------------------------------------
const Element::ElementID Element::DefaultElementID = "?id?";
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
using namespace std;
// -------------------------------------------------------------------------
const Element::ElementID Element::DefaultElementID = "?id?";
// -------------------------------------------------------------------------
void Element::addChildOut( std::shared_ptr<Element> el, size_t num )
{
if( el.get() == this )
void Element::addChildOut( std::shared_ptr<Element> el, size_t num )
{
ostringstream msg;
msg << "(" << myid << "): ПОПТКА СДЕЛАТь ССЫЛКУ НА САМОГО СЕБЯ!!!";
throw LogicException(msg.str());
}
if( el.get() == this )
{
ostringstream msg;
msg << "(" << myid << "): ПОПТКА СДЕЛАТь ССЫЛКУ НА САМОГО СЕБЯ!!!";
throw LogicException(msg.str());
}
for( const auto& it : outs )
{
if( it.el == el )
for( const auto& it : outs )
{
if( it.el == el )
{
ostringstream msg;
msg << "(" << myid << "):" << el->getId() << " уже есть в списке дочерних(такое соединение уже есть)...";
throw LogicException(msg.str());
}
}
// проверка на циклическую зависимость
// el не должен содержать в своих потомках myid
if( el->find(myid) != NULL )
{
ostringstream msg;
msg << "(" << myid << "):" << el->getId() << " уже есть в списке дочерних(такое соединение уже есть)...";
msg << "(" << myid << "): ПОПЫТКА СОЗДАТЬ ЦИКЛИЧЕКУЮ ЗАВИСИМОСТЬ!!!\n";
msg << " id" << el->getId() << " имеет в своих 'потомках' Element id=" << myid << endl;
throw LogicException(msg.str());
}
}
// проверка на циклическую зависимость
// el не должен содержать в своих потомках myid
if( el->find(myid) != NULL )
{
ostringstream msg;
msg << "(" << myid << "): ПОПЫТКА СОЗДАТЬ ЦИКЛИЧЕКУЮ ЗАВИСИМОСТЬ!!!\n";
msg << " id" << el->getId() << " имеет в своих 'потомках' Element id=" << myid << endl;
throw LogicException(msg.str());
outs.emplace_front(el, num);
}
outs.emplace_front(el, num);
}
// -------------------------------------------------------------------------
void Element::delChildOut( std::shared_ptr<Element> el )
{
for( auto it = outs.begin(); it != outs.end(); ++it )
// -------------------------------------------------------------------------
void Element::delChildOut( std::shared_ptr<Element> el )
{
if( it->el == el )
for( auto it = outs.begin(); it != outs.end(); ++it )
{
outs.erase(it);
return;
if( it->el == el )
{
outs.erase(it);
return;
}
}
}
}
// -------------------------------------------------------------------------
void Element::setChildOut()
{
bool _myout = getOut();
for( auto && it : outs )
it.el->setIn(it.num, _myout);
}
// -------------------------------------------------------------------------
std::shared_ptr<Element> Element::find(const ElementID& id )
{
for( const auto& it : outs )
// -------------------------------------------------------------------------
void Element::setChildOut()
{
if( it.el->getId() == id )
return it.el;
bool _myout = getOut();
return it.el->find(id);
for( auto && it : outs )
it.el->setIn(it.num, _myout);
}
return nullptr;
}
// -------------------------------------------------------------------------
void Element::addInput(size_t num, bool state)
{
for( auto& it : ins )
// -------------------------------------------------------------------------
std::shared_ptr<Element> Element::find(const ElementID& id )
{
if( it.num == num )
for( const auto& it : outs )
{
ostringstream msg;
msg << "(" << myid << "): попытка второй раз добавить input N" << num;
throw LogicException(msg.str());
if( it.el->getId() == id )
return it.el;
return it.el->find(id);
}
return nullptr;
}
// -------------------------------------------------------------------------
void Element::addInput(size_t num, bool state)
{
for( auto& it : ins )
{
if( it.num == num )
{
ostringstream msg;
msg << "(" << myid << "): попытка второй раз добавить input N" << num;
throw LogicException(msg.str());
}
}
ins.emplace_front(num, state);
}
// -------------------------------------------------------------------------
void Element::delInput(size_t num )
{
for( auto it = ins.begin(); it != ins.end(); ++it )
ins.emplace_front(num, state);
}
// -------------------------------------------------------------------------
void Element::delInput(size_t num )
{
if( it->num == num )
for( auto it = ins.begin(); it != ins.end(); ++it )
{
ins.erase(it);
return;
if( it->num == num )
{
ins.erase(it);
return;
}
}
}
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
} // end of namespace uniset
......@@ -25,197 +25,197 @@
//--------------------------------------------------------------------------
namespace uniset
{
// --------------------------------------------------------------------------
class LogicException:
public uniset::Exception
{
public:
LogicException(): uniset::Exception("LogicException") {}
explicit LogicException( const std::string& err): uniset::Exception(err) {}
};
class Element
{
public:
typedef std::string ElementID;
static const ElementID DefaultElementID;
enum InputType
{
unknown,
external,
internal
};
explicit Element( const ElementID& id ): myid(id) {};
virtual ~Element() {};
/*!< функция вызываемая мастером для элементов, которым требуется
работа во времени.
По умолчанию ничего не делает.
*/
virtual void tick() {}
virtual void setIn( size_t num, bool state ) = 0;
virtual bool getOut() const = 0;
inline ElementID getId() const
{
return myid;
}
virtual std::string getType() const
{
return "?type?";
}
virtual std::shared_ptr<Element> find( const ElementID& id );
virtual void addChildOut( std::shared_ptr<Element> el, size_t in_num );
virtual void delChildOut( std::shared_ptr<Element> el );
inline size_t outCount() const
{
return outs.size();
}
virtual void addInput( size_t num, bool state = false );
virtual void delInput( size_t num );
inline size_t inCount() const
{
return ins.size();
}
friend std::ostream& operator<<(std::ostream& os, Element& el )
{
return os << "[" << el.getType() << "]" << el.getId();
}
friend std::ostream& operator<<(std::ostream& os, std::shared_ptr<Element> el )
{
if( el )
return os << (*(el.get()));
return os;
}
protected:
Element(): myid(DefaultElementID) {}; // нельзя создать элемент без id
struct ChildInfo
{
ChildInfo(std::shared_ptr<Element> e, size_t n):
el(e), num(n) {}
ChildInfo(): el(0), num(0) {}
std::shared_ptr<Element> el;
size_t num;
};
typedef std::list<ChildInfo> OutputList;
OutputList outs;
virtual void setChildOut();
struct InputInfo
{
InputInfo(): num(0), state(false), type(unknown) {}
InputInfo(size_t n, bool s): num(n), state(s), type(unknown) {}
size_t num;
bool state;
InputType type;
};
typedef std::list<InputInfo> InputList;
InputList ins;
ElementID myid;
private:
};
// ---------------------------------------------------------------------------
class TOR:
public Element
{
public:
TOR( ElementID id, size_t numbers = 0, bool st = false );
virtual ~TOR();
virtual void setIn( size_t num, bool state ) override;
virtual bool getOut() const override
{
return myout;
}
virtual std::string getType() const override
{
return "OR";
}
protected:
TOR(): myout(false) {}
bool myout;
private:
};
// ---------------------------------------------------------------------------
class TAND:
public TOR
{
public:
TAND(ElementID id, size_t numbers = 0, bool st = false );
virtual ~TAND();
virtual void setIn( size_t num, bool state ) override;
virtual std::string getType() const override
{
return "AND";
}
protected:
TAND() {}
private:
};
// ---------------------------------------------------------------------------
// элемент с одним входом и выходом
class TNOT:
public Element
{
public:
TNOT( ElementID id, bool out_default );
virtual ~TNOT();
virtual bool getOut() const override
{
return myout;
}
/* num игнорируется, т.к. элемент с одним входом
*/
virtual void setIn( size_t num, bool state ) override ;
virtual std::string getType() const override
{
return "NOT";
}
virtual void addInput( size_t num, bool state = false ) override {}
virtual void delInput( size_t num ) override {}
protected:
TNOT(): myout(false) {}
bool myout;
private:
};
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
class LogicException:
public uniset::Exception
{
public:
LogicException(): uniset::Exception("LogicException") {}
explicit LogicException( const std::string& err): uniset::Exception(err) {}
};
class Element
{
public:
typedef std::string ElementID;
static const ElementID DefaultElementID;
enum InputType
{
unknown,
external,
internal
};
explicit Element( const ElementID& id ): myid(id) {};
virtual ~Element() {};
/*!< функция вызываемая мастером для элементов, которым требуется
работа во времени.
По умолчанию ничего не делает.
*/
virtual void tick() {}
virtual void setIn( size_t num, bool state ) = 0;
virtual bool getOut() const = 0;
inline ElementID getId() const
{
return myid;
}
virtual std::string getType() const
{
return "?type?";
}
virtual std::shared_ptr<Element> find( const ElementID& id );
virtual void addChildOut( std::shared_ptr<Element> el, size_t in_num );
virtual void delChildOut( std::shared_ptr<Element> el );
inline size_t outCount() const
{
return outs.size();
}
virtual void addInput( size_t num, bool state = false );
virtual void delInput( size_t num );
inline size_t inCount() const
{
return ins.size();
}
friend std::ostream& operator<<(std::ostream& os, Element& el )
{
return os << "[" << el.getType() << "]" << el.getId();
}
friend std::ostream& operator<<(std::ostream& os, std::shared_ptr<Element> el )
{
if( el )
return os << (*(el.get()));
return os;
}
protected:
Element(): myid(DefaultElementID) {}; // нельзя создать элемент без id
struct ChildInfo
{
ChildInfo(std::shared_ptr<Element> e, size_t n):
el(e), num(n) {}
ChildInfo(): el(0), num(0) {}
std::shared_ptr<Element> el;
size_t num;
};
typedef std::list<ChildInfo> OutputList;
OutputList outs;
virtual void setChildOut();
struct InputInfo
{
InputInfo(): num(0), state(false), type(unknown) {}
InputInfo(size_t n, bool s): num(n), state(s), type(unknown) {}
size_t num;
bool state;
InputType type;
};
typedef std::list<InputInfo> InputList;
InputList ins;
ElementID myid;
private:
};
// ---------------------------------------------------------------------------
class TOR:
public Element
{
public:
TOR( ElementID id, size_t numbers = 0, bool st = false );
virtual ~TOR();
virtual void setIn( size_t num, bool state ) override;
virtual bool getOut() const override
{
return myout;
}
virtual std::string getType() const override
{
return "OR";
}
protected:
TOR(): myout(false) {}
bool myout;
private:
};
// ---------------------------------------------------------------------------
class TAND:
public TOR
{
public:
TAND(ElementID id, size_t numbers = 0, bool st = false );
virtual ~TAND();
virtual void setIn( size_t num, bool state ) override;
virtual std::string getType() const override
{
return "AND";
}
protected:
TAND() {}
private:
};
// ---------------------------------------------------------------------------
// элемент с одним входом и выходом
class TNOT:
public Element
{
public:
TNOT( ElementID id, bool out_default );
virtual ~TNOT();
virtual bool getOut() const override
{
return myout;
}
/* num игнорируется, т.к. элемент с одним входом
*/
virtual void setIn( size_t num, bool state ) override ;
virtual std::string getType() const override
{
return "NOT";
}
virtual void addInput( size_t num, bool state = false ) override {}
virtual void delInput( size_t num ) override {}
protected:
TNOT(): myout(false) {}
bool myout;
private:
};
// --------------------------------------------------------------------------
} // end of namespace uniset
// ---------------------------------------------------------------------------
#endif
......@@ -110,84 +110,84 @@
// --------------------------------------------------------------------------
namespace uniset
{
// --------------------------------------------------------------------------
class LProcessor
{
public:
explicit LProcessor( const std::string& name = "" );
virtual ~LProcessor();
// --------------------------------------------------------------------------
class LProcessor
{
public:
explicit LProcessor( const std::string& name = "" );
virtual ~LProcessor();
void open( const std::string& lfile );
void open( const std::string& lfile );
inline bool isOpen() const
{
return !fSchema.empty();
}
inline bool isOpen() const
{
return !fSchema.empty();
}
virtual void execute( const std::string& lfile = "" );
virtual void execute( const std::string& lfile = "" );
virtual void terminate()
{
canceled = true;
}
virtual void terminate()
{
canceled = true;
}
inline std::shared_ptr<SchemaXML> getSchema()
{
return sch;
}
inline std::shared_ptr<SchemaXML> getSchema()
{
return sch;
}
inline int getSleepTime() const
{
return sleepTime;
}
inline int getSleepTime() const
{
return sleepTime;
}
protected:
protected:
virtual void build( const string& lfile );
virtual void build( const string& lfile );
virtual void step();
virtual void step();
virtual void getInputs();
virtual void processing();
virtual void setOuts();
virtual void getInputs();
virtual void processing();
virtual void setOuts();
struct EXTInfo
{
uniset::ObjectId sid;
UniversalIO::IOType iotype;
bool state;
std::shared_ptr<Element> el;
int numInput = { -1};
};
struct EXTInfo
{
uniset::ObjectId sid;
UniversalIO::IOType iotype;
bool state;
std::shared_ptr<Element> el;
int numInput = { -1};
};
struct EXTOutInfo
{
uniset::ObjectId sid;
UniversalIO::IOType iotype;
std::shared_ptr<Element> el;
};
struct EXTOutInfo
{
uniset::ObjectId sid;
UniversalIO::IOType iotype;
std::shared_ptr<Element> el;
};
typedef std::list<EXTInfo> EXTList;
typedef std::list<EXTOutInfo> OUTList;
typedef std::list<EXTInfo> EXTList;
typedef std::list<EXTOutInfo> OUTList;
EXTList extInputs;
OUTList extOuts;
EXTList extInputs;
OUTList extOuts;
std::shared_ptr<SchemaXML> sch;
std::shared_ptr<SchemaXML> sch;
UInterface ui;
timeout_t sleepTime = { 200 };
timeout_t smReadyTimeout = { 30000 } ; /*!< время ожидания готовности SM, мсек */
UInterface ui;
timeout_t sleepTime = { 200 };
timeout_t smReadyTimeout = { 30000 } ; /*!< время ожидания готовности SM, мсек */
std::string logname = { "" };
std::string logname = { "" };
std::atomic_bool canceled = {false};
std::atomic_bool canceled = {false};
std::string fSchema = {""};
std::string fSchema = {""};
private:
};
// --------------------------------------------------------------------------
private:
};
// --------------------------------------------------------------------------
} // end of namespace uniset
// ---------------------------------------------------------------------------
#endif
......@@ -29,57 +29,57 @@
// --------------------------------------------------------------------------
namespace uniset
{
// -------------------------------------------------------------------------
/*! Реализация LogicProccessor основанная на заказе датчиков */
class PassiveLProcessor:
public UniSetObject,
protected LProcessor
{
public:
// -------------------------------------------------------------------------
/*! Реализация LogicProccessor основанная на заказе датчиков */
class PassiveLProcessor:
public UniSetObject,
protected LProcessor
{
public:
PassiveLProcessor(uniset::ObjectId objId,
uniset::ObjectId shmID, const std::shared_ptr<SharedMemory>& ic = nullptr, const std::string& prefix = "lproc" );
virtual ~PassiveLProcessor();
PassiveLProcessor(uniset::ObjectId objId,
uniset::ObjectId shmID, const std::shared_ptr<SharedMemory>& ic = nullptr, const std::string& prefix = "lproc" );
virtual ~PassiveLProcessor();
enum Timers
{
tidStep
};
enum Timers
{
tidStep
};
static void help_print( int argc, const char* const* argv );
static void help_print( int argc, const char* const* argv );
static std::shared_ptr<PassiveLProcessor> init_plproc( int argc, const char* const* argv,
uniset::ObjectId shmID, const std::shared_ptr<SharedMemory>& ic = nullptr,
const std::string& prefix = "plproc" );
static std::shared_ptr<PassiveLProcessor> init_plproc( int argc, const char* const* argv,
uniset::ObjectId shmID, const std::shared_ptr<SharedMemory>& ic = nullptr,
const std::string& prefix = "plproc" );
protected:
PassiveLProcessor(): shm(0), maxHeartBeat(0) {};
protected:
PassiveLProcessor(): shm(0), maxHeartBeat(0) {};
virtual void step();
virtual void getInputs();
virtual void setOuts();
virtual void step();
virtual void getInputs();
virtual void setOuts();
void sysCommand( const uniset::SystemMessage* msg ) override;
void sensorInfo( const uniset::SensorMessage* sm ) override;
void timerInfo( const uniset::TimerMessage* tm ) override;
void askSensors( const UniversalIO::UIOCommand cmd );
// void initOutput();
void sysCommand( const uniset::SystemMessage* msg ) override;
void sensorInfo( const uniset::SensorMessage* sm ) override;
void timerInfo( const uniset::TimerMessage* tm ) override;
void askSensors( const UniversalIO::UIOCommand cmd );
// void initOutput();
// действия при завершении работы
virtual void sigterm( int signo ) override;
void initIterators();
virtual bool activateObject() override;
// действия при завершении работы
virtual void sigterm( int signo ) override;
void initIterators();
virtual bool activateObject() override;
std::shared_ptr<SMInterface> shm;
std::shared_ptr<SMInterface> shm;
private:
PassiveTimer ptHeartBeat;
uniset::ObjectId sidHeartBeat = { uniset::DefaultObjectId };
int maxHeartBeat = { 10 };
IOController::IOStateList::iterator itHeartBeat;
std::mutex mutex_start;
};
// --------------------------------------------------------------------------
private:
PassiveTimer ptHeartBeat;
uniset::ObjectId sidHeartBeat = { uniset::DefaultObjectId };
int maxHeartBeat = { 10 };
IOController::IOStateList::iterator itHeartBeat;
std::mutex mutex_start;
};
// --------------------------------------------------------------------------
} // end of namespace uniset
// ---------------------------------------------------------------------------
#endif
......@@ -21,205 +21,205 @@
// -----------------------------------------------------------------------------
namespace uniset
{
// -------------------------------------------------------------------------
using namespace std;
using namespace uniset::extensions;
// -------------------------------------------------------------------------
Schema::Schema()
{
}
Schema::~Schema()
{
}
// -------------------------------------------------------------------------
void Schema::link( Element::ElementID rootID, Element::ElementID childID, int numIn )
{
std::shared_ptr<Element> e1;
std::shared_ptr<Element> e2;
auto it = emap.find(rootID);
// -------------------------------------------------------------------------
using namespace std;
using namespace uniset::extensions;
// -------------------------------------------------------------------------
if( it == emap.end() )
Schema::Schema()
{
ostringstream msg;
msg << "Schema: элемент id=" << rootID << " NOT FOUND!";
throw LogicException(msg.str());
}
e1 = it->second;
it = emap.find(childID);
if( it == emap.end() )
Schema::~Schema()
{
ostringstream msg;
msg << "Schema: элемент id=" << childID << " NOT FOUND!";
throw LogicException(msg.str());
}
// -------------------------------------------------------------------------
void Schema::link( Element::ElementID rootID, Element::ElementID childID, int numIn )
{
std::shared_ptr<Element> e1;
std::shared_ptr<Element> e2;
e2 = it->second;
auto it = emap.find(rootID);
e1->addChildOut(e2, numIn);
if( it == emap.end() )
{
ostringstream msg;
msg << "Schema: элемент id=" << rootID << " NOT FOUND!";
throw LogicException(msg.str());
}
// сохраняем в список соединений
inLinks.emplace_front(e1, e2, numIn);
}
// -------------------------------------------------------------------------
void Schema::unlink( Element::ElementID rootID, Element::ElementID childID )
{
std::shared_ptr<Element> e1;
std::shared_ptr<Element> e2;
e1 = it->second;
auto it = emap.find(rootID);
it = emap.find(childID);
if( it == emap.end() )
{
ostringstream msg;
msg << "Schema: элемент id=" << rootID << " NOT FOUND!";
throw LogicException(msg.str());
}
if( it == emap.end() )
{
ostringstream msg;
msg << "Schema: элемент id=" << childID << " NOT FOUND!";
throw LogicException(msg.str());
}
e1 = it->second;
e2 = it->second;
it = emap.find( childID );
e1->addChildOut(e2, numIn);
if( it == emap.end() )
{
ostringstream msg;
msg << "Schema: element id=" << childID << " NOT FOUND!";
throw LogicException(msg.str());
// сохраняем в список соединений
inLinks.emplace_front(e1, e2, numIn);
}
// -------------------------------------------------------------------------
void Schema::unlink( Element::ElementID rootID, Element::ElementID childID )
{
std::shared_ptr<Element> e1;
std::shared_ptr<Element> e2;
e2 = it->second;
e1->delChildOut(e2);
auto it = emap.find(rootID);
// удаляем из списка соединений
for( auto && lit = inLinks.begin(); lit != inLinks.end(); ++lit )
{
if( lit->from == e1 && lit->to == e2 )
if( it == emap.end() )
{
inLinks.erase(lit);
break;
ostringstream msg;
msg << "Schema: элемент id=" << rootID << " NOT FOUND!";
throw LogicException(msg.str());
}
}
}
// -------------------------------------------------------------------------
void Schema::extlink( const string& name, Element::ElementID childID, int numIn )
{
auto it = emap.find(childID);
if( it == emap.end() )
{
ostringstream msg;
msg << "Schema: element id=" << childID << " NOT FOUND!";
throw LogicException(msg.str());
}
e1 = it->second;
auto el(it->second);
it = emap.find( childID );
// добавляем новое соединение
// el->addInput(numIn);
// уже должен быть
if( it == emap.end() )
{
ostringstream msg;
msg << "Schema: element id=" << childID << " NOT FOUND!";
throw LogicException(msg.str());
}
// заносим в список
extLinks.emplace_front(name, el, numIn);
}
// -------------------------------------------------------------------------
std::shared_ptr<Element> Schema::manage( std::shared_ptr<Element> el )
{
dinfo << "Schema: manage new element id=" << el->getId()
<< " type=" << el->getType()
<< " inputs=" << el->inCount() << endl;
e2 = it->second;
emap[el->getId()] = el;
return el;
}
// -------------------------------------------------------------------------
void Schema::remove( std::shared_ptr<Element> el )
{
for( auto && it = emap.begin(); it != emap.end(); ++it )
{
if( it->second == el )
e1->delChildOut(e2);
// удаляем из списка соединений
for( auto && lit = inLinks.begin(); lit != inLinks.end(); ++lit )
{
emap.erase(it);
break;
if( lit->from == e1 && lit->to == e2 )
{
inLinks.erase(lit);
break;
}
}
}
// помечаем внутренние связи
for( auto && lit : inLinks )
// -------------------------------------------------------------------------
void Schema::extlink( const string& name, Element::ElementID childID, int numIn )
{
if( lit.from == el )
lit.from = 0;
auto it = emap.find(childID);
if( lit.to == el )
lit.to = 0;
}
if( it == emap.end() )
{
ostringstream msg;
msg << "Schema: element id=" << childID << " NOT FOUND!";
throw LogicException(msg.str());
}
// помечаем внешние связи
for( auto && lit : extLinks )
{
if( lit.to == el )
lit.to = 0;
auto el(it->second);
// добавляем новое соединение
// el->addInput(numIn);
// уже должен быть
// заносим в список
extLinks.emplace_front(name, el, numIn);
}
// -------------------------------------------------------------------------
std::shared_ptr<Element> Schema::manage( std::shared_ptr<Element> el )
{
dinfo << "Schema: manage new element id=" << el->getId()
<< " type=" << el->getType()
<< " inputs=" << el->inCount() << endl;
}
// -------------------------------------------------------------------------
void Schema::setIn( Element::ElementID ID, int inNum, bool state )
{
auto it = emap.find(ID);
emap[el->getId()] = el;
return el;
}
// -------------------------------------------------------------------------
void Schema::remove( std::shared_ptr<Element> el )
{
for( auto && it = emap.begin(); it != emap.end(); ++it )
{
if( it->second == el )
{
emap.erase(it);
break;
}
}
if( it != emap.end() )
it->second->setIn(inNum, state);
}
// -------------------------------------------------------------------------
bool Schema::getOut( Element::ElementID ID )
{
auto it = emap.find(ID);
// помечаем внутренние связи
for( auto && lit : inLinks )
{
if( lit.from == el )
lit.from = 0;
if( it != emap.end() )
return it->second->getOut();
if( lit.to == el )
lit.to = 0;
}
ostringstream msg;
msg << "Schema: element id=" << ID << " NOT FOUND!";
throw LogicException(msg.str());
}
// -------------------------------------------------------------------------
std::shared_ptr<Element> Schema::find( Element::ElementID id )
{
auto it = emap.find(id);
// помечаем внешние связи
for( auto && lit : extLinks )
{
if( lit.to == el )
lit.to = 0;
}
if( it != emap.end() )
return it->second;
}
// -------------------------------------------------------------------------
void Schema::setIn( Element::ElementID ID, int inNum, bool state )
{
auto it = emap.find(ID);
return nullptr;
}
// -------------------------------------------------------------------------
std::shared_ptr<Element> Schema::findExtLink( const string& name )
{
// помечаем внешние связи
for( const auto& it : extLinks )
if( it != emap.end() )
it->second->setIn(inNum, state);
}
// -------------------------------------------------------------------------
bool Schema::getOut( Element::ElementID ID )
{
if( it.name == name )
return it.to;
auto it = emap.find(ID);
if( it != emap.end() )
return it->second->getOut();
ostringstream msg;
msg << "Schema: element id=" << ID << " NOT FOUND!";
throw LogicException(msg.str());
}
// -------------------------------------------------------------------------
std::shared_ptr<Element> Schema::find( Element::ElementID id )
{
auto it = emap.find(id);
return nullptr;
}
// -------------------------------------------------------------------------
std::shared_ptr<Element> Schema::findOut( const string& name )
{
// помечаем внешние связи
for( const auto& it : outList )
if( it != emap.end() )
return it->second;
return nullptr;
}
// -------------------------------------------------------------------------
std::shared_ptr<Element> Schema::findExtLink( const string& name )
{
if( it.name == name )
return it.from;
// помечаем внешние связи
for( const auto& it : extLinks )
{
if( it.name == name )
return it.to;
}
return nullptr;
}
// -------------------------------------------------------------------------
std::shared_ptr<Element> Schema::findOut( const string& name )
{
// помечаем внешние связи
for( const auto& it : outList )
{
if( it.name == name )
return it.from;
}
return nullptr;
}
// -------------------------------------------------------------------------
return nullptr;
}
// -------------------------------------------------------------------------
} // end of namespace uniset
......@@ -24,173 +24,173 @@
// --------------------------------------------------------------------------
namespace uniset
{
// --------------------------------------------------------------------------
class Schema
{
public:
Schema();
virtual ~Schema();
std::shared_ptr<Element> manage( std::shared_ptr<Element> el );
void remove( std::shared_ptr<Element> el );
void link( Element::ElementID rootID, Element::ElementID childID, int numIn );
void unlink( Element::ElementID rootID, Element::ElementID childID );
void extlink( const std::string& name, Element::ElementID childID, int numIn );
void setIn( Element::ElementID ID, int inNum, bool state );
bool getOut( Element::ElementID ID );
struct INLink;
struct EXTLink;
struct EXTOut;
typedef std::unordered_map<Element::ElementID, std::shared_ptr<Element>> ElementMap;
typedef std::list<INLink> InternalList;
typedef std::list<EXTLink> ExternalList;
typedef std::list<EXTOut> OutputsList;
// map iterator
typedef ElementMap::const_iterator iterator;
inline Schema::iterator begin()
{
return emap.begin();
}
inline Schema::iterator end()
{
return emap.end();
}
inline int size()
{
return emap.size();
}
inline bool empty()
{
return emap.empty();
}
// int. list iterator
typedef InternalList::const_iterator INTiterator;
inline Schema::INTiterator intBegin()
{
return inLinks.begin();
}
inline Schema::INTiterator intEnd()
{
return inLinks.end();
}
inline int intSize()
{
return inLinks.size();
}
inline bool intEmpty()
{
return inLinks.empty();
}
// ext. list iterator
typedef ExternalList::const_iterator EXTiterator;
inline Schema::EXTiterator extBegin()
{
return extLinks.begin();
}
inline Schema::EXTiterator extEnd()
{
return extLinks.end();
}
inline int extSize()
{
return extLinks.size();
}
inline bool extEmpty()
{
return extLinks.empty();
}
// ext. out iterator
typedef OutputsList::const_iterator OUTiterator;
inline Schema::OUTiterator outBegin()
{
return outList.begin();
}
inline Schema::OUTiterator outEnd()
{
return outList.end();
}
inline int outSize()
{
return outList.size();
}
inline bool outEmpty()
{
return outList.empty();
}
// find
std::shared_ptr<Element> find(Element::ElementID id);
std::shared_ptr<Element> findExtLink(const std::string& name);
std::shared_ptr<Element> findOut(const std::string& name);
// -----------------------------------------------
// внутренее соединения
// между элементами
struct INLink
{
INLink(std::shared_ptr<Element> f, std::shared_ptr<Element> t, int ni):
numInput(ni) {}
INLink(): numInput(0) {}
std::shared_ptr<Element> from;
std::shared_ptr<Element> to;
int numInput;
};
// внешнее соединение
// что-то на вход элемента
struct EXTLink
{
EXTLink( const std::string& n, std::shared_ptr<Element> t, int ni):
name(n), to(t), numInput(ni) {}
EXTLink(): name(""), numInput(0) {}
std::string name;
std::shared_ptr<Element> to;
int numInput;
};
// наружный выход
struct EXTOut
{
EXTOut( const std::string& n, std::shared_ptr<Element>& f):
name(n), from(f) {}
EXTOut(): name("") {}
std::string name;
std::shared_ptr<Element> from;
};
protected:
ElementMap emap; // список элеметов
InternalList inLinks;
ExternalList extLinks;
OutputsList outList;
private:
};
// ---------------------------------------------------------------------------
class SchemaXML:
public Schema
{
public:
SchemaXML();
virtual ~SchemaXML();
void read( const std::string& xmlfile );
protected:
};
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
class Schema
{
public:
Schema();
virtual ~Schema();
std::shared_ptr<Element> manage( std::shared_ptr<Element> el );
void remove( std::shared_ptr<Element> el );
void link( Element::ElementID rootID, Element::ElementID childID, int numIn );
void unlink( Element::ElementID rootID, Element::ElementID childID );
void extlink( const std::string& name, Element::ElementID childID, int numIn );
void setIn( Element::ElementID ID, int inNum, bool state );
bool getOut( Element::ElementID ID );
struct INLink;
struct EXTLink;
struct EXTOut;
typedef std::unordered_map<Element::ElementID, std::shared_ptr<Element>> ElementMap;
typedef std::list<INLink> InternalList;
typedef std::list<EXTLink> ExternalList;
typedef std::list<EXTOut> OutputsList;
// map iterator
typedef ElementMap::const_iterator iterator;
inline Schema::iterator begin()
{
return emap.begin();
}
inline Schema::iterator end()
{
return emap.end();
}
inline int size()
{
return emap.size();
}
inline bool empty()
{
return emap.empty();
}
// int. list iterator
typedef InternalList::const_iterator INTiterator;
inline Schema::INTiterator intBegin()
{
return inLinks.begin();
}
inline Schema::INTiterator intEnd()
{
return inLinks.end();
}
inline int intSize()
{
return inLinks.size();
}
inline bool intEmpty()
{
return inLinks.empty();
}
// ext. list iterator
typedef ExternalList::const_iterator EXTiterator;
inline Schema::EXTiterator extBegin()
{
return extLinks.begin();
}
inline Schema::EXTiterator extEnd()
{
return extLinks.end();
}
inline int extSize()
{
return extLinks.size();
}
inline bool extEmpty()
{
return extLinks.empty();
}
// ext. out iterator
typedef OutputsList::const_iterator OUTiterator;
inline Schema::OUTiterator outBegin()
{
return outList.begin();
}
inline Schema::OUTiterator outEnd()
{
return outList.end();
}
inline int outSize()
{
return outList.size();
}
inline bool outEmpty()
{
return outList.empty();
}
// find
std::shared_ptr<Element> find(Element::ElementID id);
std::shared_ptr<Element> findExtLink(const std::string& name);
std::shared_ptr<Element> findOut(const std::string& name);
// -----------------------------------------------
// внутренее соединения
// между элементами
struct INLink
{
INLink(std::shared_ptr<Element> f, std::shared_ptr<Element> t, int ni):
numInput(ni) {}
INLink(): numInput(0) {}
std::shared_ptr<Element> from;
std::shared_ptr<Element> to;
int numInput;
};
// внешнее соединение
// что-то на вход элемента
struct EXTLink
{
EXTLink( const std::string& n, std::shared_ptr<Element> t, int ni):
name(n), to(t), numInput(ni) {}
EXTLink(): name(""), numInput(0) {}
std::string name;
std::shared_ptr<Element> to;
int numInput;
};
// наружный выход
struct EXTOut
{
EXTOut( const std::string& n, std::shared_ptr<Element>& f):
name(n), from(f) {}
EXTOut(): name("") {}
std::string name;
std::shared_ptr<Element> from;
};
protected:
ElementMap emap; // список элеметов
InternalList inLinks;
ExternalList extLinks;
OutputsList outList;
private:
};
// ---------------------------------------------------------------------------
class SchemaXML:
public Schema
{
public:
SchemaXML();
virtual ~SchemaXML();
void read( const std::string& xmlfile );
protected:
};
// --------------------------------------------------------------------------
} // end of namespace uniset
// ---------------------------------------------------------------------------
#endif
......@@ -23,129 +23,129 @@
// -----------------------------------------------------------------------------
namespace uniset
{
// -------------------------------------------------------------------------
using namespace std;
using namespace uniset::extensions;
// -------------------------------------------------------------------------
SchemaXML::SchemaXML()
{
}
SchemaXML::~SchemaXML()
{
}
// -------------------------------------------------------------------------
void SchemaXML::read( const string& xmlfile )
{
UniXML xml;
const string sec("elements");
const string conn_sec("connections");
// try
// {
xml.open(xmlfile);
// }
// catch(...){}
xmlNode* root( xml.findNode(xml.getFirstNode(), sec) );
if( !root )
// -------------------------------------------------------------------------
using namespace std;
using namespace uniset::extensions;
// -------------------------------------------------------------------------
SchemaXML::SchemaXML()
{
ostringstream msg;
msg << "(SchemaXML::read): не нашли корневого раздела " << sec;
throw LogicException(msg.str());
}
// Считываем список элементов
UniXML::iterator it(root);
if( !it.goChildren() )
SchemaXML::~SchemaXML()
{
ostringstream msg;
msg << "(SchemaXML::read): не удалось перейти к списку элементов " << sec;
throw LogicException(msg.str());
}
for( ; it.getCurrent(); it.goNext() )
// -------------------------------------------------------------------------
void SchemaXML::read( const string& xmlfile )
{
string type(xml.getProp(it, "type"));
string ID(xml.getProp(it, "id"));
int inCount = xml.getPIntProp(it, "inCount", 1);
if( type == "OR" )
manage( make_shared<TOR>(ID, inCount) );
else if( type == "AND" )
manage( make_shared<TAND>(ID, inCount) );
else if( type == "Delay" )
{
int delayMS = xml.getIntProp(it, "delayMS");
manage( make_shared<TDelay>(ID, delayMS, inCount) );
}
else if( type == "NOT" )
{
bool defout = xml.getIntProp(it, "default_out_state");
manage( make_shared<TNOT>(ID, defout) );
}
else
UniXML xml;
const string sec("elements");
const string conn_sec("connections");
// try
// {
xml.open(xmlfile);
// }
// catch(...){}
xmlNode* root( xml.findNode(xml.getFirstNode(), sec) );
if( !root )
{
ostringstream msg;
msg << "(SchemaXML::read): НЕИЗВЕСТНЫЙ ТИП ЭЛЕМЕНТА -->" << type;
msg << "(SchemaXML::read): не нашли корневого раздела " << sec;
throw LogicException(msg.str());
}
}
// Строим связи
xmlNode* conNode( xml.findNode(xml.getFirstNode(), conn_sec) );
// Считываем список элементов
UniXML::iterator it(root);
if( !conNode )
{
ostringstream msg;
msg << "(SchemaXML::read): не нашли корневого раздела " << conn_sec;
throw LogicException(msg.str());
}
it = conNode;
if( !it.goChildren() )
{
ostringstream msg;
msg << "(SchemaXML::read): не удалось перейти к списку элементов " << sec;
throw LogicException(msg.str());
}
if( !it.goChildren() )
{
ostringstream msg;
msg << "(SchemaXML::read): не удалось перейти к списку элементов " << conn_sec;
throw LogicException(msg.str());
}
for( ; it.getCurrent(); it.goNext() )
{
string type(xml.getProp(it, "type"));
string ID(xml.getProp(it, "id"));
int inCount = xml.getPIntProp(it, "inCount", 1);
if( type == "OR" )
manage( make_shared<TOR>(ID, inCount) );
else if( type == "AND" )
manage( make_shared<TAND>(ID, inCount) );
else if( type == "Delay" )
{
int delayMS = xml.getIntProp(it, "delayMS");
manage( make_shared<TDelay>(ID, delayMS, inCount) );
}
else if( type == "NOT" )
{
bool defout = xml.getIntProp(it, "default_out_state");
manage( make_shared<TNOT>(ID, defout) );
}
else
{
ostringstream msg;
msg << "(SchemaXML::read): НЕИЗВЕСТНЫЙ ТИП ЭЛЕМЕНТА -->" << type;
throw LogicException(msg.str());
}
}
for( ; it.getCurrent(); it.goNext() )
{
string type(xml.getProp(it, "type"));
string fID(xml.getProp(it, "from"));
string tID(xml.getProp(it, "to"));
int toIn = xml.getIntProp(it, "toInput");
// Строим связи
xmlNode* conNode( xml.findNode(xml.getFirstNode(), conn_sec) );
if( type == "ext" )
if( !conNode )
{
dinfo << "SchemaXML: set EXTlink: from=" << fID << " to=" << tID << " toInput=" << toIn << endl;
extlink(fID, tID, toIn);
ostringstream msg;
msg << "(SchemaXML::read): не нашли корневого раздела " << conn_sec;
throw LogicException(msg.str());
}
else if( type == "int" )
it = conNode;
if( !it.goChildren() )
{
dinfo << "SchemaXML: set INTlink: from=" << fID << " to=" << tID << " toInput=" << toIn << endl;
link(fID, tID, toIn);
ostringstream msg;
msg << "(SchemaXML::read): не удалось перейти к списку элементов " << conn_sec;
throw LogicException(msg.str());
}
else if( type == "out" )
for( ; it.getCurrent(); it.goNext() )
{
auto el = find(fID);
string type(xml.getProp(it, "type"));
string fID(xml.getProp(it, "from"));
string tID(xml.getProp(it, "to"));
int toIn = xml.getIntProp(it, "toInput");
if( !el )
if( type == "ext" )
{
ostringstream msg;
msg << "(SchemaXML::read): НЕ НАЙДЕН ЭЛЕМЕНТ С ID=" << fID;
throw LogicException(msg.str());
dinfo << "SchemaXML: set EXTlink: from=" << fID << " to=" << tID << " toInput=" << toIn << endl;
extlink(fID, tID, toIn);
}
else if( type == "int" )
{
dinfo << "SchemaXML: set INTlink: from=" << fID << " to=" << tID << " toInput=" << toIn << endl;
link(fID, tID, toIn);
}
else if( type == "out" )
{
auto el = find(fID);
dinfo << "SchemaXML: set Out: from=" << fID << " to=" << tID << endl;
outList.emplace_front(tID, el);
if( !el )
{
ostringstream msg;
msg << "(SchemaXML::read): НЕ НАЙДЕН ЭЛЕМЕНТ С ID=" << fID;
throw LogicException(msg.str());
}
dinfo << "SchemaXML: set Out: from=" << fID << " to=" << tID << endl;
outList.emplace_front(tID, el);
}
}
}
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
} // end of namespace uniset
......@@ -20,56 +20,56 @@
// -----------------------------------------------------------------------------
namespace uniset
{
// -------------------------------------------------------------------------
using namespace std;
using namespace uniset::extensions;
// -------------------------------------------------------------------------
TAND::TAND(ElementID id, size_t num, bool st):
TOR(id, num, st)
{
}
// -------------------------------------------------------------------------
using namespace std;
using namespace uniset::extensions;
// -------------------------------------------------------------------------
TAND::TAND(ElementID id, size_t num, bool st):
TOR(id, num, st)
{
}
TAND::~TAND()
{
}
// -------------------------------------------------------------------------
void TAND::setIn(size_t num, bool state )
{
// cout << this << ": input " << num << " set " << state << endl;
for( auto& it : ins )
TAND::~TAND()
{
if( it.num == num )
}
// -------------------------------------------------------------------------
void TAND::setIn(size_t num, bool state )
{
// cout << this << ": input " << num << " set " << state << endl;
for( auto& it : ins )
{
if( it.state == state )
return; // вход не менялся можно вообще прервать проверку
if( it.num == num )
{
if( it.state == state )
return; // вход не менялся можно вообще прервать проверку
it.state = state;
break;
it.state = state;
break;
}
}
}
bool prev = myout;
bool brk = false; // признак досрочного завершения проверки
bool prev = myout;
bool brk = false; // признак досрочного завершения проверки
// проверяем изменился ли выход
// для тригера 'AND' проверка до первого 0
for( auto& it : ins )
{
if( !it.state )
// проверяем изменился ли выход
// для тригера 'AND' проверка до первого 0
for( auto& it : ins )
{
myout = false;
brk = true;
break;
if( !it.state )
{
myout = false;
brk = true;
break;
}
}
}
if( !brk )
myout = true;
if( !brk )
myout = true;
dinfo << this << ": myout " << myout << endl;
dinfo << this << ": myout " << myout << endl;
if( prev != myout )
Element::setChildOut();
}
// -------------------------------------------------------------------------
if( prev != myout )
Element::setChildOut();
}
// -------------------------------------------------------------------------
} // end of namespace uniset
......@@ -20,86 +20,86 @@
// -----------------------------------------------------------------------------
namespace uniset
{
// -------------------------------------------------------------------------
using namespace std;
using namespace uniset::extensions;
// -------------------------------------------------------------------------
TDelay::TDelay(Element::ElementID id, timeout_t delayMS, size_t inCount):
Element(id),
myout(false),
delay(delayMS)
{
if( inCount != 0 )
// -------------------------------------------------------------------------
using namespace std;
using namespace uniset::extensions;
// -------------------------------------------------------------------------
TDelay::TDelay(Element::ElementID id, timeout_t delayMS, size_t inCount):
Element(id),
myout(false),
delay(delayMS)
{
// создаём заданное количество входов
for( unsigned int i = 1; i <= inCount; i++ )
ins.emplace_front(i, false); // addInput(i,st);
if( inCount != 0 )
{
// создаём заданное количество входов
for( unsigned int i = 1; i <= inCount; i++ )
ins.emplace_front(i, false); // addInput(i,st);
}
}
}
TDelay::~TDelay()
{
}
// -------------------------------------------------------------------------
void TDelay::setIn( size_t num, bool state )
{
bool prev = myout;
// сбрасываем сразу
if( !state )
TDelay::~TDelay()
{
pt.setTiming(0); // reset timer
myout = false;
dinfo << this << ": set " << myout << endl;
}
// -------------------------------------------------------------------------
void TDelay::setIn( size_t num, bool state )
{
bool prev = myout;
if( prev != myout )
Element::setChildOut();
// сбрасываем сразу
if( !state )
{
pt.setTiming(0); // reset timer
myout = false;
dinfo << this << ": set " << myout << endl;
return;
}
if( prev != myout )
Element::setChildOut();
// if( state )
return;
}
// выставляем без задержки
if( delay <= 0 )
{
pt.setTiming(0); // reset timer
myout = true;
dinfo << this << ": set " << myout << endl;
// if( state )
if( prev != myout )
Element::setChildOut();
// выставляем без задержки
if( delay <= 0 )
{
pt.setTiming(0); // reset timer
myout = true;
dinfo << this << ": set " << myout << endl;
return;
}
if( prev != myout )
Element::setChildOut();
return;
}
// засекаем, если ещё не установлен таймер
if( !myout && !prev ) // т.е. !myout && prev != myout
// засекаем, если ещё не установлен таймер
if( !myout && !prev ) // т.е. !myout && prev != myout
{
dinfo << this << ": set timer " << delay << " [msec]" << endl;
pt.setTiming(delay);
}
}
// -------------------------------------------------------------------------
void TDelay::tick()
{
dinfo << this << ": set timer " << delay << " [msec]" << endl;
pt.setTiming(delay);
if( pt.getInterval() != 0 && pt.checkTime() )
{
myout = true;
pt.setTiming(0); // reset timer
dinfo << getType() << "(" << myid << "): TIMER!!!! myout=" << myout << endl;
Element::setChildOut();
}
}
}
// -------------------------------------------------------------------------
void TDelay::tick()
{
if( pt.getInterval() != 0 && pt.checkTime() )
// -------------------------------------------------------------------------
bool TDelay::getOut() const
{
myout = true;
pt.setTiming(0); // reset timer
dinfo << getType() << "(" << myid << "): TIMER!!!! myout=" << myout << endl;
Element::setChildOut();
return myout;
}
}
// -------------------------------------------------------------------------
bool TDelay::getOut() const
{
return myout;
}
// -------------------------------------------------------------------------
void TDelay::setDelay( timeout_t timeMS )
{
delay = timeMS;
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
void TDelay::setDelay( timeout_t timeMS )
{
delay = timeMS;
}
// -------------------------------------------------------------------------
} // end of namespace uniset
......@@ -22,41 +22,41 @@
// --------------------------------------------------------------------------
namespace uniset
{
// ---------------------------------------------------------------------------
// "ON" delay element
// Сбрасывается без задержки.. а срабатывает с задержкой.
class TDelay:
public Element
{
// ---------------------------------------------------------------------------
// "ON" delay element
// Сбрасывается без задержки.. а срабатывает с задержкой.
class TDelay:
public Element
{
public:
TDelay( Element::ElementID id, timeout_t delayMS = 0, size_t inCount = 0 );
virtual ~TDelay();
public:
TDelay( Element::ElementID id, timeout_t delayMS = 0, size_t inCount = 0 );
virtual ~TDelay();
virtual void tick() override;
virtual void setIn( size_t num, bool state ) override;
virtual bool getOut() const override;
virtual std::string getType() const override
{
return "Delay";
}
virtual void tick() override;
virtual void setIn( size_t num, bool state ) override;
virtual bool getOut() const override;
virtual std::string getType() const override
{
return "Delay";
}
void setDelay( timeout_t timeMS );
inline timeout_t getDelay() const
{
return delay;
}
void setDelay( timeout_t timeMS );
inline timeout_t getDelay() const
{
return delay;
}
protected:
TDelay(): myout(false), delay(0) {};
protected:
TDelay(): myout(false), delay(0) {};
bool myout;
PassiveTimer pt;
timeout_t delay;
bool myout;
PassiveTimer pt;
timeout_t delay;
private:
};
// --------------------------------------------------------------------------
private:
};
// --------------------------------------------------------------------------
} // end of namespace uniset
// ---------------------------------------------------------------------------
#endif
......
......@@ -21,28 +21,28 @@
// -----------------------------------------------------------------------------
namespace uniset
{
// -------------------------------------------------------------------------
using namespace std;
using namespace uniset::extensions;
// -------------------------------------------------------------------------
TNOT::TNOT( ElementID id, bool out_default ):
Element(id),
myout(out_default)
{
ins.emplace_front(1, !out_default);
}
// -------------------------------------------------------------------------
TNOT::~TNOT()
{
}
// -------------------------------------------------------------------------
void TNOT::setIn( size_t num, bool state )
{
bool prev = myout;
myout = !state;
// -------------------------------------------------------------------------
using namespace std;
using namespace uniset::extensions;
// -------------------------------------------------------------------------
TNOT::TNOT( ElementID id, bool out_default ):
Element(id),
myout(out_default)
{
ins.emplace_front(1, !out_default);
}
// -------------------------------------------------------------------------
TNOT::~TNOT()
{
}
// -------------------------------------------------------------------------
void TNOT::setIn( size_t num, bool state )
{
bool prev = myout;
myout = !state;
if( prev != myout )
Element::setChildOut();
}
// -------------------------------------------------------------------------
if( prev != myout )
Element::setChildOut();
}
// -------------------------------------------------------------------------
} // end of namespace uniset
......@@ -21,69 +21,69 @@
// -----------------------------------------------------------------------------
namespace uniset
{
// -------------------------------------------------------------------------
using namespace std;
using namespace uniset::extensions;
// -------------------------------------------------------------------------
TOR::TOR(ElementID id, size_t num, bool st):
Element(id),
myout(false)
{
if( num != 0 )
// -------------------------------------------------------------------------
using namespace std;
using namespace uniset::extensions;
// -------------------------------------------------------------------------
TOR::TOR(ElementID id, size_t num, bool st):
Element(id),
myout(false)
{
// создаём заданное количество входов
for( unsigned int i = 1; i <= num; i++ )
if( num != 0 )
{
ins.emplace_front(i, st); // addInput(i,st);
// создаём заданное количество входов
for( unsigned int i = 1; i <= num; i++ )
{
ins.emplace_front(i, st); // addInput(i,st);
if( st == true )
myout = true;
if( st == true )
myout = true;
}
}
}
}
TOR::~TOR()
{
}
// -------------------------------------------------------------------------
void TOR::setIn( size_t num, bool state )
{
// cout << getType() << "(" << myid << "): input " << num << " set " << state << endl;
for( auto& it : ins )
TOR::~TOR()
{
if( it.num == num )
}
// -------------------------------------------------------------------------
void TOR::setIn( size_t num, bool state )
{
// cout << getType() << "(" << myid << "): input " << num << " set " << state << endl;
for( auto& it : ins )
{
if( it.state == state )
return; // вход не менялся можно вообще прервать проверку
if( it.num == num )
{
if( it.state == state )
return; // вход не менялся можно вообще прервать проверку
it.state = state;
break;
it.state = state;
break;
}
}
}
bool prev = myout;
bool brk = false; // признак досрочного завершения проверки
bool prev = myout;
bool brk = false; // признак досрочного завершения проверки
// проверяем изменился ли выход
// для тригера 'OR' проверка до первой единицы
for( auto& it : ins )
{
if( it.state )
// проверяем изменился ли выход
// для тригера 'OR' проверка до первой единицы
for( auto& it : ins )
{
myout = true;
brk = true;
break;
if( it.state )
{
myout = true;
brk = true;
break;
}
}
}
if( !brk )
myout = false;
if( !brk )
myout = false;
dinfo << this << ": myout " << myout << endl;
dinfo << this << ": myout " << myout << endl;
if( prev != myout )
Element::setChildOut();
}
// -------------------------------------------------------------------------
if( prev != myout )
Element::setChildOut();
}
// -------------------------------------------------------------------------
} // end of namespace uniset
......@@ -412,6 +412,6 @@ std::string MQTTPublisher::MQTTTextInfo::replace( RangeInfo* ri, long value )
txt = replace_all(txt, "%rmax", smax.str());
txt = replace_all(txt, "%r", r.str());
return std::move(txt);
return txt;
}
//--------------------------------------------------------------------------------
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -758,7 +758,7 @@ const std::string MBTCPMultiMaster::MBSlaveInfo::getShortInfo() const
<< " persistent-connection=" << !force_disconnect
<< ")";
return std::move(s.str());
return s.str();
}
// -----------------------------------------------------------------------------
uniset::SimpleInfo* MBTCPMultiMaster::getInfo( const char* userparam )
......
......@@ -27,43 +27,43 @@
// --------------------------------------------------------------------------
namespace uniset
{
// -----------------------------------------------------------------------------
class RTUExchange:
public MBExchange
{
public:
RTUExchange( uniset::ObjectId objId, uniset::ObjectId shmID,
const std::shared_ptr<SharedMemory>& ic = nullptr, const std::string& prefix = "rs" );
virtual ~RTUExchange();
// -----------------------------------------------------------------------------
class RTUExchange:
public MBExchange
{
public:
RTUExchange( uniset::ObjectId objId, uniset::ObjectId shmID,
const std::shared_ptr<SharedMemory>& ic = nullptr, const std::string& prefix = "rs" );
virtual ~RTUExchange();
/*! глобальная функция для инициализации объекта */
static std::shared_ptr<RTUExchange> init_rtuexchange( int argc, const char* const* argv,
uniset::ObjectId shmID, const std::shared_ptr<SharedMemory>& ic = nullptr,
const std::string& prefix = "rs" );
/*! глобальная функция для инициализации объекта */
static std::shared_ptr<RTUExchange> init_rtuexchange( int argc, const char* const* argv,
uniset::ObjectId shmID, const std::shared_ptr<SharedMemory>& ic = nullptr,
const std::string& prefix = "rs" );
/*! глобальная функция для вывода help-а */
static void help_print( int argc, const char* const* argv );
/*! глобальная функция для вывода help-а */
static void help_print( int argc, const char* const* argv );
protected:
std::shared_ptr<ModbusRTUMaster> mbrtu;
std::mutex mbMutex;
std::string devname;
ComPort::Speed defSpeed;
bool use485F;
bool transmitCtl;
protected:
std::shared_ptr<ModbusRTUMaster> mbrtu;
std::mutex mbMutex;
std::string devname;
ComPort::Speed defSpeed;
bool use485F;
bool transmitCtl;
virtual void step() override;
virtual bool poll() override;
virtual void step() override;
virtual bool poll() override;
virtual std::shared_ptr<ModbusClient> initMB( bool reopen = false ) override;
virtual bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML::iterator& it ) override;
virtual std::shared_ptr<ModbusClient> initMB( bool reopen = false ) override;
virtual bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML::iterator& it ) override;
private:
RTUExchange();
private:
RTUExchange();
bool rs_pre_clean;
};
// --------------------------------------------------------------------------
bool rs_pre_clean;
};
// --------------------------------------------------------------------------
} // end of namespace uniset
// -----------------------------------------------------------------------------
#endif // _RS_EXCHANGE_H_
......
......@@ -25,95 +25,95 @@
// --------------------------------------------------------------------------
namespace uniset
{
// -----------------------------------------------------------------------------
class ModbusRTUMaster;
// -----------------------------------------------------------------------------
class RTUStorage
{
public:
explicit RTUStorage( ModbusRTU::ModbusAddr addr );
~RTUStorage();
// -----------------------------------------------------------------------------
class ModbusRTUMaster;
// -----------------------------------------------------------------------------
class RTUStorage
{
public:
explicit RTUStorage( ModbusRTU::ModbusAddr addr );
~RTUStorage();
void poll( const std::shared_ptr<ModbusRTUMaster>& mb )
throw(ModbusRTU::mbException);
void poll( const std::shared_ptr<ModbusRTUMaster>& mb )
throw(ModbusRTU::mbException);
inline ModbusRTU::ModbusAddr getAddress()
{
return addr;
}
inline bool ping()
{
return pingOK;
}
inline ModbusRTU::ModbusAddr getAddress()
{
return addr;
}
inline bool ping()
{
return pingOK;
}
inline void setPollADC( bool set )
{
pollADC = set;
}
inline void setPollDI( bool set )
{
pollDI = set;
}
inline void setPollDIO( bool set )
{
pollDIO = set;
}
inline void setPollUNIO( bool set )
{
pollUNIO = set;
}
inline void setPollADC( bool set )
{
pollADC = set;
}
inline void setPollDI( bool set )
{
pollDI = set;
}
inline void setPollDIO( bool set )
{
pollDIO = set;
}
inline void setPollUNIO( bool set )
{
pollUNIO = set;
}
enum RTUJack
{
nUnknown,
nJ1, // UNIO48 (FPGA0)
nJ2, // UNIO48 (FPGA1)
nJ5, // DIO 16
nX1, // АЦП (8)
nX2, // АЦП (8)
nX4, // DI (8)
nX5 // DI (8)
};
enum RTUJack
{
nUnknown,
nJ1, // UNIO48 (FPGA0)
nJ2, // UNIO48 (FPGA1)
nJ5, // DIO 16
nX1, // АЦП (8)
nX2, // АЦП (8)
nX4, // DI (8)
nX5 // DI (8)
};
static RTUJack s2j( const std::string& jack );
static std::string j2s( RTUJack j );
static RTUJack s2j( const std::string& jack );
static std::string j2s( RTUJack j );
long getInt( RTUJack jack, unsigned short channel, UniversalIO::IOType t );
float getFloat( RTUJack jack, unsigned short channel, UniversalIO::IOType t );
bool getState( RTUJack jack, unsigned short channel, UniversalIO::IOType t );
long getInt( RTUJack jack, unsigned short channel, UniversalIO::IOType t );
float getFloat( RTUJack jack, unsigned short channel, UniversalIO::IOType t );
bool getState( RTUJack jack, unsigned short channel, UniversalIO::IOType t );
static ModbusRTU::ModbusData getRegister( RTUJack jack, unsigned short channel, UniversalIO::IOType t );
static ModbusRTU::ModbusData getRegister( RTUJack jack, unsigned short channel, UniversalIO::IOType t );
static ModbusRTU::SlaveFunctionCode getFunction( RTUJack jack, unsigned short channel, UniversalIO::IOType t );
static ModbusRTU::SlaveFunctionCode getFunction( RTUJack jack, unsigned short channel, UniversalIO::IOType t );
// ДОДЕЛАТЬ: setState, setValue
void print();
// ДОДЕЛАТЬ: setState, setValue
void print();
friend std::ostream& operator<<(std::ostream& os, RTUStorage& m );
friend std::ostream& operator<<(std::ostream& os, RTUStorage* m );
friend std::ostream& operator<<(std::ostream& os, RTUStorage& m );
friend std::ostream& operator<<(std::ostream& os, RTUStorage* m );
protected:
ModbusRTU::ModbusAddr addr;
bool pingOK;
protected:
ModbusRTU::ModbusAddr addr;
bool pingOK;
bool pollADC;
bool pollDI;
bool pollDIO;
bool pollUNIO;
bool pollADC;
bool pollDI;
bool pollDIO;
bool pollUNIO;
float adc[8]; // АЦП
bool di[16]; // Порт 16DI
bool dio_do[16]; // Порт 16DIO DO
bool dio_di[16]; // Порт 16DIO DI
float dio_ai[16]; // Порт 16DIO AI
float dio_ao[16]; // Порт 16DIO AO
bool unio_do[48]; // Порт UNIO48 DO
bool unio_di[48]; // Порт UNIO48 DI
float unio_ai[24]; // Порт UNIO48 AI
float unio_ao[24]; // Порт UNIO48 AO
};
// --------------------------------------------------------------------------
float adc[8]; // АЦП
bool di[16]; // Порт 16DI
bool dio_do[16]; // Порт 16DIO DO
bool dio_di[16]; // Порт 16DIO DI
float dio_ai[16]; // Порт 16DIO AI
float dio_ao[16]; // Порт 16DIO AO
bool unio_do[48]; // Порт UNIO48 DO
bool unio_di[48]; // Порт UNIO48 DI
float unio_ai[24]; // Порт UNIO48 AI
float unio_ao[24]; // Порт UNIO48 AO
};
// --------------------------------------------------------------------------
} // end of namespace uniset
// --------------------------------------------------------------------------
#endif // _RTUSTORAGE_H_
......
......@@ -19,8 +19,10 @@
#include <iomanip>
#include <getopt.h>
#include "Debug.h"
#include "UniSetTypes.h"
#include "modbus/ModbusRTUMaster.h"
#include "modbus/ModbusHelpers.h"
#include "modbus/ModbusTCPMaster.h"
#include "MTR.h"
// --------------------------------------------------------------------------
using namespace uniset;
......@@ -39,6 +41,8 @@ static struct option longopts[] =
{ "use485F", no_argument, 0, 'y' },
{ "num-cycles", required_argument, 0, 'l' },
{ "timeout", required_argument, 0, 't' },
{ "iaddr", required_argument, 0, 'i' },
{ "port", required_argument, 0, 'p' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
......@@ -49,12 +53,16 @@ static void print_help()
printf("[--read04] slaveaddr reg mtrtype - read from MTR (mtrtype: T1...T10,T16,T17,F1)\n");
printf("[-m|--read-model] slaveaddr - read model name from MTR\n");
printf("[-n|--read-serial] slaveaddr - read serial number from MTR\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-l|--num-cycles] num - Number of cycles of exchange. Default: -1 infinitely.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("\nRTU prameters:\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("\nTCP prameters:\n");
printf("[-i|--iaddr] ip - Modbus server ip. Default: 127.0.0.1\n");
printf("[-p|--port] port - Modbus server port. Default: 502.\n");
}
// --------------------------------------------------------------------------
enum Command
......@@ -67,7 +75,7 @@ enum Command
};
// --------------------------------------------------------------------------
static char* checkArg( int ind, int argc, char* argv[] );
static void readMTR( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr,
static void readMTR( ModbusClient* mb, ModbusRTU::ModbusAddr addr,
ModbusRTU::ModbusData reg, MTR::MTRType t, Command cmd );
// --------------------------------------------------------------------------
......@@ -88,12 +96,14 @@ int main( int argc, char** argv )
int use485 = 0;
int ncycles = -1;
MTR::MTRType mtrtype = MTR::mtUnknown;
string iaddr("127.0.0.1");
int port = 502;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hvyq:r:d:s:t:x:m:n:", longopts, &optindex);
opt = getopt_long(argc, argv, "hvyq:r:d:s:t:x:m:n:i:p:", longopts, &optindex);
if( opt == -1 )
break;
......@@ -176,6 +186,14 @@ int main( int argc, char** argv )
ncycles = uni_atoi(optarg);
break;
case 'i':
iaddr = string(optarg);
break;
case 'p':
port = uni_atoi(optarg);
break;
case '?':
default:
printf("? argumnet\n");
......@@ -190,14 +208,27 @@ int main( int argc, char** argv )
<< endl;
}
ModbusRTUMaster mb(dev, use485);
ModbusClient* mb = nullptr;
if( !iaddr.empty() )
{
auto mbtcp = new ModbusTCPMaster();
mbtcp->connect(iaddr, port);
// mbtcp->setForceDisconnect(!persist);
mb = mbtcp;
}
else
{
auto mbrtu = new ModbusRTUMaster(dev, use485);
mbrtu->setSpeed(speed);
mb = mbrtu;
}
if( verb )
dlog->addLevel(Debug::ANY);
mb.setTimeout(tout);
mb.setSpeed(speed);
mb.setLog(dlog);
mb->setTimeout(tout);
mb->setLog(dlog);
int nc = 1;
......@@ -222,7 +253,7 @@ int main( int argc, char** argv )
<< endl;
}
readMTR( &mb, slaveaddr, reg, mtrtype, cmd );
readMTR( mb, slaveaddr, reg, mtrtype, cmd );
}
break;
......@@ -234,7 +265,7 @@ int main( int argc, char** argv )
<< endl;
}
string s(MTR::getModelNumber(&mb, slaveaddr));
string s = MTR::getModelNumber(mb, slaveaddr);
cout << (s.empty() ? "Don`t read model name." : s) << endl;
return 0;
}
......@@ -248,7 +279,7 @@ int main( int argc, char** argv )
<< endl;
}
string s(MTR::getSerialNumber(&mb, slaveaddr));
string s(MTR::getSerialNumber(mb, slaveaddr));
cout << (s.empty() ? "Don`t read serial number." : s) << endl;
return 0;
}
......@@ -303,7 +334,7 @@ char* checkArg( int i, int argc, char* argv[] )
return 0;
}
// --------------------------------------------------------------------------
void readMTR( ModbusRTUMaster* mb, ModbusRTU::ModbusAddr addr,
void readMTR( ModbusClient* mb, ModbusRTU::ModbusAddr addr,
ModbusRTU::ModbusData reg, MTR::MTRType mtrType, Command cmd )
{
int count = MTR::wsize(mtrType);
......
......@@ -23,6 +23,7 @@
#include <math.h>
#include "Debug.h"
#include "modbus/ModbusRTUMaster.h"
#include "modbus/ModbusTCPMaster.h"
#include "modbus/ModbusHelpers.h"
#include "extensions/MTR.h"
// --------------------------------------------------------------------------
......@@ -40,13 +41,15 @@ static struct option longopts[] =
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "speed", required_argument, 0, 's' },
{ "stop-bits", required_argument, 0, 'i' },
{ "parity", required_argument, 0, 'p' },
{ "stop-bits", required_argument, 0, 'o' },
{ "parity", required_argument, 0, 'a' },
{ "use485F", no_argument, 0, 'y' },
{ "min-addr", required_argument, 0, 'b' },
{ "max-addr", required_argument, 0, 'e' },
{ "model", required_argument, 0, 'x' },
{ "serial", required_argument, 0, 'z' },
{ "iaddr", required_argument, 0, 'i' },
{ "port", required_argument, 0, 'p' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
......@@ -56,21 +59,26 @@ static void print_help()
printf("[--read] mtraddr - read configuration from MTR\n");
printf("[--save] mtraddr confile - save configureation to MTR\n");
printf(" mtraddr=0x00 - autodetect addr\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[--stop-bits] n - stop bits [1,2]. Default: 1\n");
printf("[--parity] par - parity [odd,even,no]. Default: no\n");
printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
printf("[--autodetect-speed] slaveaddr [reg fn] - detect speed\n");
printf(" reg - register of test. Default: 0\n");
printf(" fn - function of test [0x01,0x02,0x03,0x04]. Default: 0x04\n");
printf("[--autodetect-slave] [reg fn] - find slave\n");
printf(" reg - register of test. Default: 0\n");
printf(" fn - function of test [0x01,0x02,0x03,0x04]. Default: 0x04\n");
printf("[--min-addr] - start addres for autodetect. Default: 0\n");
printf("[--max-addr] - end addres for autodetect. Default: 254\n");
printf("\nRTU prameters:\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[--parity] par - parity [odd,even,no]. Default: no\n");
printf("[--stop-bits] n - stop bits [1,2]. Default: 1\n");
printf("[--autodetect-speed] slaveaddr [reg fn] - detect speed\n");
printf(" reg - register of test. Default: 0\n");
printf(" fn - function of test [0x01,0x02,0x03,0x04]. Default: 0x04\n");
printf("\nTCP prameters:\n");
printf("[-i|--iaddr] ip - Modbus server ip. Default: 127.0.0.1\n");
printf("[-p|--port] port - Modbus server port. Default: 502.\n");
printf("\n");
}
// --------------------------------------------------------------------------
......@@ -109,17 +117,14 @@ int main( int argc, char** argv )
int use485 = 0;
ComPort::StopBits sbits = ComPort::OneBit;
ComPort::Parity parity = ComPort::NoParity;
// ModbusRTU::ModbusAddr b=255;
//
// cout << "b=" << (int)b << " b++=" << (int)(b++) << endl;
// return 0;
string iaddr("127.0.0.1");
int port = 502;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hvw:r:x:d:s:t:l:n:yb:e:x:z:", longopts, &optindex);
opt = getopt_long(argc, argv, "hvw:r:x:d:s:t:l:n:yb:e:x:z:i:p:o:a:", longopts, &optindex);
if( opt == -1 )
break;
......@@ -171,7 +176,7 @@ int main( int argc, char** argv )
speed = string(optarg);
break;
case 'p':
case 'a':
par = string(optarg);
if( !par.compare("odd") )
......@@ -187,7 +192,7 @@ int main( int argc, char** argv )
tout = atoi(optarg);
break;
case 'i':
case 'o':
if( atoi(optarg) == 2 )
sbits = ComPort::TwoBits;
......@@ -245,6 +250,14 @@ int main( int argc, char** argv )
}
break;
case 'i':
iaddr = string(optarg);
break;
case 'p':
port = uni_atoi(optarg);
break;
case '?':
default:
printf("? argumnet\n");
......@@ -259,16 +272,29 @@ int main( int argc, char** argv )
<< endl;
}
ModbusRTUMaster mb(dev, use485);
ModbusClient* mb = nullptr;
if( !iaddr.empty() )
{
auto mbtcp = new ModbusTCPMaster();
mbtcp->connect(iaddr, port);
// mbtcp->setForceDisconnect(!persist);
mb = mbtcp;
}
else
{
auto mbrtu = new ModbusRTUMaster(dev, use485);
mbrtu->setSpeed(speed);
mbrtu->setParity(parity);
mbrtu->setStopBits(sbits);
mb = mbrtu;
}
if( verb )
dlog->addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
mb.setTimeout(tout);
mb.setSpeed(speed);
mb.setParity(parity);
mb.setStopBits(sbits);
mb.setLog(dlog);
mb->setTimeout(tout);
mb->setLog(dlog);
switch(cmd)
{
......@@ -286,9 +312,9 @@ int main( int argc, char** argv )
if( verb )
cout << "(mtr-setup): save: autodetect slave addr... (speed=" << speed << ")" << endl;
mb.setTimeout(50);
slaveaddr = ModbusHelpers::autodetectSlave(&mb, beg, end, MTR::regModelNumber, ModbusRTU::fnReadInputRegisters);
mb.setTimeout(tout);
mb->setTimeout(50);
slaveaddr = ModbusHelpers::autodetectSlave(mb, beg, end, MTR::regModelNumber, ModbusRTU::fnReadInputRegisters);
mb->setTimeout(tout);
}
if( speed.empty() )
......@@ -296,10 +322,14 @@ int main( int argc, char** argv )
if( verb )
cout << "(mtr-setup): save: autodetect speed... (addr=" << ModbusRTU::addr2str(slaveaddr) << ")" << endl;
mb.setTimeout(50);
ComPort::Speed s = ModbusHelpers::autodetectSpeed(&mb, slaveaddr, MTR::regModelNumber, ModbusRTU::fnReadInputRegisters);
mb.setSpeed(s);
mb.setTimeout(tout);
auto mbrtu = dynamic_cast<ModbusRTUMaster*>(mb);
if( mbrtu )
{
mb->setTimeout(50);
ComPort::Speed s = ModbusHelpers::autodetectSpeed(mbrtu, slaveaddr, MTR::regModelNumber, ModbusRTU::fnReadInputRegisters);
mbrtu->setSpeed(s);
mbrtu->setTimeout(tout);
}
}
if( verb )
......@@ -309,7 +339,7 @@ int main( int argc, char** argv )
<< " speed=" << speed
<< endl;
return MTR::update_configuration(&mb, slaveaddr, mtrconfile, verb) ? 0 : 1;
return MTR::update_configuration(mb, slaveaddr, mtrconfile, verb) ? 0 : 1;
}
break;
......@@ -327,7 +357,7 @@ int main( int argc, char** argv )
try
{
ModbusRTU::ModbusAddr a = ModbusHelpers::autodetectSlave(&mb, beg, end, reg, fn);
ModbusRTU::ModbusAddr a = ModbusHelpers::autodetectSlave(mb, beg, end, reg, fn);
cout << "(mtr-setup): autodetect modbus slave: " << ModbusRTU::addr2str(a) << endl;
}
catch( uniset::TimeOut )
......@@ -340,6 +370,14 @@ int main( int argc, char** argv )
case cmdDetectSpeed:
{
auto mbrtu = dynamic_cast<ModbusRTUMaster*>(mb);
if( !mbrtu )
{
cerr << "autodetect speed only for RTU interface.." << endl;
return 1;
}
if( verb )
{
cout << "(mtr-setup): autodetect speed: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
......@@ -350,7 +388,7 @@ int main( int argc, char** argv )
try
{
ComPort::Speed s = ModbusHelpers::autodetectSpeed(&mb, slaveaddr, reg, fn);
ComPort::Speed s = ModbusHelpers::autodetectSpeed(mbrtu, slaveaddr, reg, fn);
cout << "(mtr-setup): autodetect: slaveaddr=" << ModbusRTU::addr2str(slaveaddr)
<< " speed=" << ComPort::getSpeed(s) << endl;
}
......@@ -371,7 +409,7 @@ int main( int argc, char** argv )
<< endl;
}
cout << "model: " << MTR::getModelNumber(&mb, slaveaddr) << endl;
cout << "model: " << MTR::getModelNumber(mb, slaveaddr) << endl;
}
break;
......@@ -384,7 +422,7 @@ int main( int argc, char** argv )
<< endl;
}
cout << "serial: " << MTR::getSerialNumber(&mb, slaveaddr) << endl;
cout << "serial: " << MTR::getSerialNumber(mb, slaveaddr) << endl;
}
break;
......
// -------------------------------------------------------------------------
#include <sstream>
#include <limits>
#include <Poco/Net/NetException.h>
#include "UniSetTypes.h"
#include "MBTCPTestServer.h"
......@@ -23,7 +24,7 @@ MBTCPTestServer::MBTCPTestServer( const std::unordered_set<ModbusAddr>& _vaddr,
sslot(NULL),
vaddr(_vaddr),
verbose(verb),
replyVal(-1),
replyVal(std::numeric_limits<uint32_t>::max()),
forceSingleCoilCmd(false),
lastWriteOutputSingleRegister(0),
lastForceCoilsQ(0, 0),
......@@ -122,7 +123,7 @@ ModbusRTU::mbErrCode MBTCPTestServer::readCoilStatus( ReadCoilMessage& query,
if( query.count <= 1 )
{
if( replyVal != -1 )
if( replyVal != std::numeric_limits<uint32_t>::max() )
reply.addData(replyVal);
else
reply.addData(d);
......@@ -136,7 +137,7 @@ ModbusRTU::mbErrCode MBTCPTestServer::readCoilStatus( ReadCoilMessage& query,
for( ; num < query.count; num++, reg++ )
{
if( replyVal != -1 )
if( replyVal != std::numeric_limits<uint32_t>::max() )
reply.addData(replyVal);
else
reply.addData(d);
......@@ -167,7 +168,7 @@ ModbusRTU::mbErrCode MBTCPTestServer::readInputStatus( ReadInputStatusMessage& q
d.b[3] = 1;
d.b[7] = 1;
if( replyVal == -1 )
if( replyVal == std::numeric_limits<uint32_t>::max() )
{
size_t bnum = 0;
size_t i = 0;
......@@ -197,7 +198,7 @@ ModbusRTU::mbErrCode MBTCPTestServer::readInputStatus( ReadInputStatusMessage& q
}
// -------------------------------------------------------------------------
mbErrCode MBTCPTestServer::readInputRegisters( ReadInputMessage& query,
ReadInputRetMessage& reply )
ReadInputRetMessage& reply )
{
if( disabled )
return ModbusRTU::erTimeOut;
......@@ -207,7 +208,7 @@ mbErrCode MBTCPTestServer::readInputRegisters( ReadInputMessage& query,
if( query.count <= 1 )
{
if( replyVal != -1 )
if( replyVal != std::numeric_limits<uint32_t>::max() )
reply.addData(replyVal);
else
reply.addData(query.start);
......@@ -221,7 +222,7 @@ mbErrCode MBTCPTestServer::readInputRegisters( ReadInputMessage& query,
for( ; num < query.count; num++, reg++ )
{
if( replyVal != -1 )
if( replyVal != std::numeric_limits<uint32_t>::max() )
reply.addData(replyVal);
else
reply.addData(reg);
......@@ -252,7 +253,7 @@ ModbusRTU::mbErrCode MBTCPTestServer::readOutputRegisters(
if( query.count <= 1 )
{
if( replyVal != -1 )
if( replyVal != std::numeric_limits<uint32_t>::max() )
reply.addData(replyVal);
else
reply.addData(query.start);
......@@ -266,7 +267,7 @@ ModbusRTU::mbErrCode MBTCPTestServer::readOutputRegisters(
for( ; num < query.count; num++, reg++ )
{
if( replyVal != -1 )
if( replyVal != std::numeric_limits<uint32_t>::max() )
reply.addData(replyVal);
else
reply.addData(reg);
......@@ -539,7 +540,7 @@ ModbusRTU::mbErrCode MBTCPTestServer::diagnostics( ModbusRTU::DiagnosticMessage&
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBTCPTestServer::read4314( ModbusRTU::MEIMessageRDI& query,
ModbusRTU::MEIMessageRetRDI& reply )
ModbusRTU::MEIMessageRetRDI& reply )
{
if( disabled )
return ModbusRTU::erTimeOut;
......
......@@ -19,7 +19,7 @@ class MBTCPTestServer
verbose = state;
}
inline void setReply( long val )
inline void setReply( uint32_t val )
{
replyVal = val;
}
......@@ -47,7 +47,7 @@ class MBTCPTestServer
{
return forceSingleCoilCmd;
}
inline int getLastWriteOutputSingleRegister()
inline int16_t getLastWriteOutputSingleRegister()
{
return lastWriteOutputSingleRegister;
}
......@@ -73,26 +73,26 @@ class MBTCPTestServer
/*! обработка 0x01 */
uniset::ModbusRTU::mbErrCode readCoilStatus( uniset::ModbusRTU::ReadCoilMessage& query,
uniset::ModbusRTU::ReadCoilRetMessage& reply );
uniset::ModbusRTU::ReadCoilRetMessage& reply );
/*! обработка 0x02 */
uniset::ModbusRTU::mbErrCode readInputStatus( uniset::ModbusRTU::ReadInputStatusMessage& query,
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
/*! обработка 0x03 */
uniset::ModbusRTU::mbErrCode readOutputRegisters( uniset::ModbusRTU::ReadOutputMessage& query,
uniset::ModbusRTU::ReadOutputRetMessage& reply );
uniset::ModbusRTU::ReadOutputRetMessage& reply );
/*! обработка 0x04 */
uniset::ModbusRTU::mbErrCode readInputRegisters( uniset::ModbusRTU::ReadInputMessage& query,
uniset::ModbusRTU::ReadInputRetMessage& reply );
uniset::ModbusRTU::ReadInputRetMessage& reply );
/*! обработка 0x05 */
uniset::ModbusRTU::mbErrCode forceSingleCoil( uniset::ModbusRTU::ForceSingleCoilMessage& query,
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
/*! обработка 0x0F */
uniset::ModbusRTU::mbErrCode forceMultipleCoils( uniset::ModbusRTU::ForceCoilsMessage& query,
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
/*! обработка 0x10 */
......@@ -105,25 +105,25 @@ class MBTCPTestServer
uniset::ModbusRTU::mbErrCode diagnostics( uniset::ModbusRTU::DiagnosticMessage& query,
uniset::ModbusRTU::DiagnosticRetMessage& reply );
uniset::ModbusRTU::DiagnosticRetMessage& 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::JournalCommandRetMessage& reply );
/*! обработка запроса на установку времени */
uniset::ModbusRTU::mbErrCode setDateTime( uniset::ModbusRTU::SetDateTimeMessage& query,
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
/*! обработка запроса удалённого сервиса */
uniset::ModbusRTU::mbErrCode remoteService( uniset::ModbusRTU::RemoteServiceMessage& query,
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
uniset::ModbusRTU::mbErrCode fileTransfer( uniset::ModbusRTU::FileTransferMessage& query,
uniset::ModbusRTU::FileTransferRetMessage& reply );
uniset::ModbusRTU::FileTransferRetMessage& reply );
/*! интерфейс ModbusSlave для обмена по RS */
......@@ -131,9 +131,9 @@ class MBTCPTestServer
std::unordered_set<uniset::ModbusRTU::ModbusAddr> vaddr; /*!< адреса данного узла */
bool verbose;
long replyVal;
uint32_t replyVal;
bool forceSingleCoilCmd;
int lastWriteOutputSingleRegister;
int16_t lastWriteOutputSingleRegister;
uniset::ModbusRTU::ForceCoilsMessage lastForceCoilsQ;
uniset::ModbusRTU::WriteOutputMessage lastWriteOutputQ;
float f2_test_value = {0.0};
......
......@@ -15,7 +15,7 @@ cd -
--mbtcp-filter-value 1 \
--mbtcp-gateway-iaddr localhost \
--mbtcp-gateway-port 20048 \
--mbtcp-polltime 50 --mbtcp-recv-timeout 500
--mbtcp-polltime 50 --mbtcp-recv-timeout 500
#--mbtcp-log-add-levels any
#--mbtcp-default-mbinit-ok 1
#--dlog-add-levels any
......
......@@ -222,12 +222,12 @@ TEST_CASE("MBTCPMaster: 0x03 (read register outputs or memories or read word out
REQUIRE( ui->getValue(1004) == -10 );
REQUIRE( ui->getValue(1005) == -10 );
REQUIRE( ui->getValue(1006) == -10 );
mbs->setReply(0);
mbs->setReply(1);
msleep(polltime + 200);
REQUIRE( ui->getValue(1003) == 0 );
REQUIRE( ui->getValue(1004) == 0 );
REQUIRE( ui->getValue(1005) == 0 );
REQUIRE( ui->getValue(1006) == 0 );
REQUIRE( ui->getValue(1003) == 1 );
REQUIRE( ui->getValue(1004) == 1 );
REQUIRE( ui->getValue(1005) == 1 );
REQUIRE( ui->getValue(1006) == 1 );
mbs->setReply(65535);
msleep(polltime + 200);
REQUIRE( ui->getValue(1003) == -1 );
......@@ -236,10 +236,14 @@ TEST_CASE("MBTCPMaster: 0x03 (read register outputs or memories or read word out
REQUIRE( ui->getValue(1006) == -1 );
REQUIRE( ui->getValue(1007) == 65535 ); // unsigned
mbs->setReply(0xffff);
mbs->setReply( std::numeric_limits<uint16_t>::max() );
msleep(polltime + 200);
REQUIRE( (uint16_t)ui->getValue(1009) == std::numeric_limits<uint16_t>::max() ); // U2
mbs->setReply( std::numeric_limits<int16_t>::max() );
msleep(polltime + 200);
REQUIRE( ui->getValue(1008) == 0xffffffff ); // I2
REQUIRE( ui->getValue(1009) == 0xffffffff ); // U2
REQUIRE( (int16_t)ui->getValue(1008) == std::numeric_limits<int16_t>::max() ); // I2
mbs->setReply(0xff);
msleep(polltime + 200);
REQUIRE( ui->getValue(1008) == 0x00ff00ff ); // I2
......@@ -281,10 +285,14 @@ TEST_CASE("MBTCPMaster: 0x04 (read input registers or memories or read word outp
REQUIRE( ui->getValue(1013) == -1 );
REQUIRE( ui->getValue(1014) == 65535 ); // unsigned
mbs->setReply(0xffff);
mbs->setReply( std::numeric_limits<uint16_t>::max() );
msleep(polltime + 200);
REQUIRE( ui->getValue(1015) == 0xffffffff ); // I2
REQUIRE( ui->getValue(1016) == 0xffffffff ); // U2
REQUIRE( (uint16_t)ui->getValue(1009) == std::numeric_limits<uint16_t>::max() ); // U2
mbs->setReply( std::numeric_limits<int16_t>::max() );
msleep(polltime + 200);
REQUIRE( (int16_t)ui->getValue(1008) == std::numeric_limits<int16_t>::max() ); // I2
mbs->setReply(0xff);
msleep(polltime + 200);
REQUIRE( ui->getValue(1015) == 0x00ff00ff ); // I2
......@@ -457,23 +465,23 @@ TEST_CASE("MBTCPMaster: 0x10 (write register outputs or memories)", "[modbus][0x
REQUIRE( q.addr == slaveADDR );
REQUIRE( q.start == 31 );
REQUIRE( q.quant == 6 );
REQUIRE( q.data[0] == (unsigned short)(-100) );
REQUIRE( q.data[2] == (unsigned short)(-10) );
REQUIRE( q.data[3] == (unsigned short)(-32767) );
REQUIRE( q.data[0] == (uint16_t)(-100) );
REQUIRE( q.data[2] == (uint16_t)(-10) );
REQUIRE( q.data[3] == (uint16_t)(-32767) );
}
SECTION("I2")
{
ui->setValue(1023, 0xffffffff);
REQUIRE( ui->getValue(1023) == 0xffffffff );
ui->setValue(1023, std::numeric_limits<uint32_t>::max());
REQUIRE( (uint32_t)ui->getValue(1023) == std::numeric_limits<uint32_t>::max() );
msleep(polltime + 200);
ModbusRTU::WriteOutputMessage q = mbs->getLastWriteOutput();
REQUIRE( q.addr == slaveADDR );
REQUIRE( q.start == 31 );
REQUIRE( q.quant == 6 );
REQUIRE( q.data[4] == 0xffff );
REQUIRE( q.data[5] == 0xffff );
REQUIRE( q.data[4] == std::numeric_limits<uint16_t>::max() );
REQUIRE( q.data[5] == std::numeric_limits<uint16_t>::max() );
}
}
// -----------------------------------------------------------------------------
......
......@@ -127,6 +127,8 @@ TEST_CASE("MBTCPMultiMaster: rotate channel", "[modbus][mbmaster][mbtcpmultimast
InitTest();
CHECK( ui->isExist(mbID) );
mbs1->setReply(0);
msleep(polltime + 1000);
REQUIRE( ui->getValue(1003) == 0 );
mbs1->setReply(100);
mbs2->setReply(10);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -202,8 +202,8 @@ void SMDBServer::help_print( int argc, const char* const* argv )
}
// -----------------------------------------------------------------------------
SMDBServer* SMDBServer::init_smdbserver( int argc, const char* const* argv,
uniset::ObjectId icID, SharedMemory* ic,
const std::string& prefix )
uniset::ObjectId icID, SharedMemory* ic,
const std::string& prefix )
{
string name = conf->getArgParam("--" + prefix + "-name", "DBServer");
......
......@@ -948,7 +948,7 @@ const std::string UNetReceiver::getShortInfo() const noexcept
<< endl
<< "\t[ qsize=" << qpack.size() << " recv=" << statRecvPerSec << " update=" << statUpPerSec << " per sec ]";
return std::move(s.str());
return s.str();
}
// -----------------------------------------------------------------------------
UNetReceiver::pack_guard::pack_guard( mutex& _m, UNetReceiver::UpdateStrategy _s ):
......
......@@ -76,7 +76,7 @@ static UniSetUDP::UDPMessage receive( unsigned int pnum = 0, timeout_t tout = 20
ncycle--;
}
return std::move(pack);
return pack;
}
// -----------------------------------------------------------------------------
void send( UniSetUDP::UDPMessage& pack, int tout = 2000 )
......@@ -298,7 +298,7 @@ TEST_CASE("[UNetUDP]: check receiver", "[unetudp][receiver]")
REQUIRE( ui->getValue(11) == 0 );
send(pack);
msleep(200);
msleep(500);
REQUIRE( ui->getValue(8) == 100 );
REQUIRE( ui->getValue(9) == -100 );
REQUIRE( ui->getValue(10) == 1 );
......@@ -316,7 +316,7 @@ TEST_CASE("[UNetUDP]: check receiver", "[unetudp][receiver]")
pack.addDData(10, false);
pack.addDData(11, true);
send(pack);
msleep(200);
msleep(500);
REQUIRE( ui->getValue(8) == 10 );
REQUIRE( ui->getValue(9) == -10 );
REQUIRE( ui->getValue(10) == 0 );
......
......@@ -27,126 +27,126 @@
// --------------------------------------------------------------------------
namespace uniset
{
// -----------------------------------------------------------------------------
/*!
\page pageUniExchange Обмен между узлами на основе TCP.
\par Обмен построен на основе функций IOControl-ера получения списка дискретных
и аналоговых датчиков. Работает через удалённые CORBA-вызовы.
\par Процесс считывает из конфигурационного файла список узлов которые необходимо
опрашивать (точнее список IOControl-еров), запускается поток обмена, в котором
эти узлы ПОСЛЕДОВАТЕЛЬНО опрашиваются..
\par Пример записи в конфигурационном файле для опроса пяти узлов...
\code
<UniExchange name="UniExchange">
<item name="UniExchange2" node="Node2"/>
<item id="3001" node_id="Node2"/>
<item name="UniExchange3" node="Node3"/>
<item name="UniExchange4" node="Node4"/>
<item name="UniExchange5" node="Node5"/>
</UniExchange>
\endcode
Запись можно делать по "id" или по "name"
*/
// -----------------------------------------------------------------------------
class UniExchange:
public IOController
{
public:
UniExchange( uniset::ObjectId id, uniset::ObjectId shmID,
const std::shared_ptr<SharedMemory>& ic = nullptr, const std::string& prefix = "unet" );
virtual ~UniExchange();
void execute();
static std::shared_ptr<UniExchange> init_exchange( int argc, const char* const* argv,
uniset::ObjectId shmID, const std::shared_ptr<SharedMemory>& ic = nullptr,
const std::string& prefix = "unet" );
/*! глобальная функция для вывода help-а */
static void help_print( int argc, const char** argv );
virtual IOController_i::ShortMapSeq* getSensors() override;
protected:
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
virtual void askSensors( UniversalIO::UIOCommand cmd );
virtual void sigterm( int signo ) override;
xmlNode* cnode = { 0 };
std::string s_field = { "" };
std::string s_fvalue = { "" };
std::shared_ptr<SMInterface> shm;
struct SInfo
{
// т.к. содержится rwmutex с запрещённым конструктором копирования
// приходится здесь тоже объявлять разрешенными только операции "перемещения"
SInfo( const SInfo& r ) = delete;
SInfo& operator=(const SInfo& r) = delete;
SInfo( SInfo&& r ) = default;
SInfo& operator=(SInfo&& r) = default;
SInfo():
val(0),
id(uniset::DefaultObjectId),
type(UniversalIO::UnknownIOType)
{}
IOController::IOStateList::iterator ioit;
long val;
long id;
UniversalIO::IOType type;
uniset::uniset_rwmutex val_lock;
};
typedef std::vector<SInfo> SList;
struct NetNodeInfo
{
// т.к. содержится SList в котором rwmutex с запрещённым конструктором копирования
// приходится здесь тоже объявлять разрешенными только операции "перемещения"
NetNodeInfo( const NetNodeInfo& r ) = delete;
NetNodeInfo& operator=(const NetNodeInfo& r) = delete;
NetNodeInfo( NetNodeInfo&& r ) = default;
NetNodeInfo& operator=(NetNodeInfo&& r) = default;
NetNodeInfo();
CORBA::Object_var oref;
IOController_i_var shm;
uniset::ObjectId id;
uniset::ObjectId node;
uniset::ObjectId sidConnection; /*!< датчик связи */
IOController::IOStateList::iterator conn_it;
SList smap;
void update(IOController_i::ShortMapSeq_var& map, const std::shared_ptr<SMInterface>& shm );
};
typedef std::list<NetNodeInfo> NetNodeList;
NetNodeList nlst;
void readConfiguration();
bool readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec );
bool initItem( UniXML::iterator& it );
void updateLocalData();
void initIterators();
timeout_t polltime = { 200 };
PassiveTimer ptUpdate;
bool init_ok = { false };
SList mymap;
size_t maxIndex = { 0 };
timeout_t smReadyTimeout = { 15000 }; // msec
private:
};
// --------------------------------------------------------------------------
// -----------------------------------------------------------------------------
/*!
\page pageUniExchange Обмен между узлами на основе TCP.
\par Обмен построен на основе функций IOControl-ера получения списка дискретных
и аналоговых датчиков. Работает через удалённые CORBA-вызовы.
\par Процесс считывает из конфигурационного файла список узлов которые необходимо
опрашивать (точнее список IOControl-еров), запускается поток обмена, в котором
эти узлы ПОСЛЕДОВАТЕЛЬНО опрашиваются..
\par Пример записи в конфигурационном файле для опроса пяти узлов...
\code
<UniExchange name="UniExchange">
<item name="UniExchange2" node="Node2"/>
<item id="3001" node_id="Node2"/>
<item name="UniExchange3" node="Node3"/>
<item name="UniExchange4" node="Node4"/>
<item name="UniExchange5" node="Node5"/>
</UniExchange>
\endcode
Запись можно делать по "id" или по "name"
*/
// -----------------------------------------------------------------------------
class UniExchange:
public IOController
{
public:
UniExchange( uniset::ObjectId id, uniset::ObjectId shmID,
const std::shared_ptr<SharedMemory>& ic = nullptr, const std::string& prefix = "unet" );
virtual ~UniExchange();
void execute();
static std::shared_ptr<UniExchange> init_exchange( int argc, const char* const* argv,
uniset::ObjectId shmID, const std::shared_ptr<SharedMemory>& ic = nullptr,
const std::string& prefix = "unet" );
/*! глобальная функция для вывода help-а */
static void help_print( int argc, const char** argv );
virtual IOController_i::ShortMapSeq* getSensors() override;
protected:
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
virtual void askSensors( UniversalIO::UIOCommand cmd );
virtual void sigterm( int signo ) override;
xmlNode* cnode = { 0 };
std::string s_field = { "" };
std::string s_fvalue = { "" };
std::shared_ptr<SMInterface> shm;
struct SInfo
{
// т.к. содержится rwmutex с запрещённым конструктором копирования
// приходится здесь тоже объявлять разрешенными только операции "перемещения"
SInfo( const SInfo& r ) = delete;
SInfo& operator=(const SInfo& r) = delete;
SInfo( SInfo&& r ) = default;
SInfo& operator=(SInfo&& r) = default;
SInfo():
val(0),
id(uniset::DefaultObjectId),
type(UniversalIO::UnknownIOType)
{}
IOController::IOStateList::iterator ioit;
long val;
long id;
UniversalIO::IOType type;
uniset::uniset_rwmutex val_lock;
};
typedef std::vector<SInfo> SList;
struct NetNodeInfo
{
// т.к. содержится SList в котором rwmutex с запрещённым конструктором копирования
// приходится здесь тоже объявлять разрешенными только операции "перемещения"
NetNodeInfo( const NetNodeInfo& r ) = delete;
NetNodeInfo& operator=(const NetNodeInfo& r) = delete;
NetNodeInfo( NetNodeInfo&& r ) = default;
NetNodeInfo& operator=(NetNodeInfo&& r) = default;
NetNodeInfo();
CORBA::Object_var oref;
IOController_i_var shm;
uniset::ObjectId id;
uniset::ObjectId node;
uniset::ObjectId sidConnection; /*!< датчик связи */
IOController::IOStateList::iterator conn_it;
SList smap;
void update(IOController_i::ShortMapSeq_var& map, const std::shared_ptr<SMInterface>& shm );
};
typedef std::list<NetNodeInfo> NetNodeList;
NetNodeList nlst;
void readConfiguration();
bool readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec );
bool initItem( UniXML::iterator& it );
void updateLocalData();
void initIterators();
timeout_t polltime = { 200 };
PassiveTimer ptUpdate;
bool init_ok = { false };
SList mymap;
size_t maxIndex = { 0 };
timeout_t smReadyTimeout = { 15000 }; // msec
private:
};
// --------------------------------------------------------------------------
} // end of namespace uniset
// -----------------------------------------------------------------------------
#endif // UniExchange_H_
......@@ -26,103 +26,103 @@
//--------------------------------------------------------------------------
namespace uniset
{
//--------------------------------------------------------------------------
class DigitalFilter
{
public:
DigitalFilter ( unsigned int bufsize = 5, double T = 0, double lsq = 0.2,
int iir_thr = 10000, double iir_coeff_prev = 0.5,
double iir_coeff_new = 0.5 );
~DigitalFilter ();
// T <=0 - отключить вторую ступень фильтра
void setSettings( unsigned int bufsize, double T, double lsq,
int iir_thr, double iir_coeff_prev, double iir_coeff_new );
// Усреднение с учётом СКОС
// На вход подается новое значение
// возвращается фильтрованное с учётом
// предыдущих значений...
int filter1( int newValue );
// RC-фильтр
int filterRC( int newVal );
// медианный фильтр
int median( int newval );
// адаптивный фильтр по схеме наименьших квадратов
int leastsqr( int newval );
// рекурсивный фильтр
int filterIIR( int newval );
// получить текущее фильтрованное значение
int current1();
int currentRC();
int currentMedian();
int currentLS();
int currentIIR();
// просто добавить очередное значение
void add( int newValue );
void init( int val );
// void init( list<int>& data );
inline int size()
{
return buf.size();
}
inline double middle()
{
return M;
}
inline double sko()
{
return S;
}
friend std::ostream& operator<<(std::ostream& os, const DigitalFilter& d);
friend std::ostream& operator<<(std::ostream& os, const DigitalFilter* d);
private:
// Первая ступень фильтра
double firstLevel();
// Вторая ступень фильтра, математическая реализация RC фильтра
double secondLevel( double val );
double Ti; // Постоянная времени для апериодического звена в милисекундах
double val; // Текущее значение второй ступени фильтра
double M; // Среднее арифметическое
double S; // Среднеквадратичное отклонение
PassiveTimer tmr;
typedef std::deque<int> FIFOBuffer;
FIFOBuffer buf;
unsigned int maxsize;
typedef std::vector<int> MedianVector;
MedianVector mvec;
bool mvec_sorted; // флаг, что mvec остортирован (заполнен)
typedef std::vector<double> Coeff;
Coeff w; // Вектор коэффициентов для filterIIR
double lsparam; // Параметр для filterIIR
double ls; // Последнее значение, возвращённое filterIIR
int thr; // Порог для изменений, обрабатываемых рекурсивным фильтром
int prev; // Последнее значение, возвращённое рекурсивным фильтром
// Коэффициенты для рекурсивного фильтра
double coeff_prev;
double coeff_new;
};
// -------------------------------------------------------------------------
//--------------------------------------------------------------------------
class DigitalFilter
{
public:
DigitalFilter ( unsigned int bufsize = 5, double T = 0, double lsq = 0.2,
int iir_thr = 10000, double iir_coeff_prev = 0.5,
double iir_coeff_new = 0.5 );
~DigitalFilter ();
// T <=0 - отключить вторую ступень фильтра
void setSettings( unsigned int bufsize, double T, double lsq,
int iir_thr, double iir_coeff_prev, double iir_coeff_new );
// Усреднение с учётом СКОС
// На вход подается новое значение
// возвращается фильтрованное с учётом
// предыдущих значений...
int filter1( int newValue );
// RC-фильтр
int filterRC( int newVal );
// медианный фильтр
int median( int newval );
// адаптивный фильтр по схеме наименьших квадратов
int leastsqr( int newval );
// рекурсивный фильтр
int filterIIR( int newval );
// получить текущее фильтрованное значение
int current1();
int currentRC();
int currentMedian();
int currentLS();
int currentIIR();
// просто добавить очередное значение
void add( int newValue );
void init( int val );
// void init( list<int>& data );
inline int size()
{
return buf.size();
}
inline double middle()
{
return M;
}
inline double sko()
{
return S;
}
friend std::ostream& operator<<(std::ostream& os, const DigitalFilter& d);
friend std::ostream& operator<<(std::ostream& os, const DigitalFilter* d);
private:
// Первая ступень фильтра
double firstLevel();
// Вторая ступень фильтра, математическая реализация RC фильтра
double secondLevel( double val );
double Ti; // Постоянная времени для апериодического звена в милисекундах
double val; // Текущее значение второй ступени фильтра
double M; // Среднее арифметическое
double S; // Среднеквадратичное отклонение
PassiveTimer tmr;
typedef std::deque<int> FIFOBuffer;
FIFOBuffer buf;
unsigned int maxsize;
typedef std::vector<int> MedianVector;
MedianVector mvec;
bool mvec_sorted; // флаг, что mvec остортирован (заполнен)
typedef std::vector<double> Coeff;
Coeff w; // Вектор коэффициентов для filterIIR
double lsparam; // Параметр для filterIIR
double ls; // Последнее значение, возвращённое filterIIR
int thr; // Порог для изменений, обрабатываемых рекурсивным фильтром
int prev; // Последнее значение, возвращённое рекурсивным фильтром
// Коэффициенты для рекурсивного фильтра
double coeff_prev;
double coeff_new;
};
// -------------------------------------------------------------------------
} // end of namespace uniset
//--------------------------------------------------------------------------
#endif // DigitalFilter_H_
......
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