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

Добавил MVSlaveTest для локальной наладки MBSlave.

parent 9c5730a2
......@@ -407,6 +407,7 @@ AC_CONFIG_FILES([Makefile
extensions/MQTTPublisher/libUniSet2MQTTPublisher.pc
extensions/tests/Makefile
extensions/tests/SMemoryTest/Makefile
extensions/tests/MBSlaveTest/Makefile
testsuite/Makefile
python/lib/Makefile
python/lib/pyUniSet/Makefile
......
......@@ -1903,29 +1903,29 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
}
catch( UniSetTypes::NameNotFound& ex )
{
mbwarn << myname << "(write): " << ex << endl;
mbwarn << myname << "(real_write_prop): " << ex << endl;
return ModbusRTU::erBadDataAddress;
}
catch( UniSetTypes::OutOfRange& ex )
{
mbwarn << myname << "(write): " << ex << endl;
mbwarn << myname << "(real_write_prop): " << ex << endl;
return ModbusRTU::erBadDataValue;
}
catch( const Exception& ex )
{
if( pingOK )
mbcrit << myname << "(write): " << ex << endl;
mbcrit << myname << "(real_write_prop): " << ex << endl;
}
catch( const CORBA::SystemException& ex )
{
if( pingOK )
mbcrit << myname << "(write): СORBA::SystemException: "
mbcrit << myname << "(real_write_prop): СORBA::SystemException: "
<< ex.NP_minorString() << endl;
}
catch(...)
{
if( pingOK )
mbcrit << myname << "(write) catch ..." << endl;
mbcrit << myname << "(real_write_prop) catch ..." << endl;
}
pingOK = false;
......
noinst_PROGRAMS = mbslave-test
mbslave_test_LDADD = $(top_builddir)/lib/libUniSet2.la \
$(top_builddir)/extensions/lib/libUniSet2Extensions.la \
$(top_builddir)/extensions/SharedMemory/libUniSet2SharedMemory.la \
$(top_builddir)/extensions/ModbusSlave/libUniSet2MBSlave.la \
$(SIGC_LIBS) $(COMCPP_LIBS)
mbslave_test_CPPFLAGS = -I$(top_builddir)/include \
-I$(top_builddir)/extensions/include \
-I$(top_builddir)/extensions/SharedMemory \
-I$(top_builddir)/extensions/ModbusSlave \
$(SIGC_CFLAGS) $(COMCPP_CFLAGS)
mbslave_test_SOURCES = TestProc_SK.cc TestProc.cc mbslave-test.cc
BUILT_SOURCES=TestProc_SK.cc TestProc_SK.h
TestProc_SK.cc TestProc_SK.h: testproc.src.xml
$(top_builddir)/Utilities/codegen/@PACKAGE@-codegen -l $(top_builddir)/Utilities/codegen --ask -n TestProc --local-include --topdir $(top_builddir)/ --no-main testproc.src.xml
clean-local:
rm -rf *_SK.cc *_SK.h
include $(top_builddir)/include.mk
#include <iomanip>
#include "Exceptions.h"
#include "TestProc.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
// -----------------------------------------------------------------------------
TestProc::TestProc( UniSetTypes::ObjectId id, xmlNode* confnode ):
TestProc_SK( id, confnode ),
state(false)
{
loglevels.push_back(Debug::INFO);
loglevels.push_back(Debug::WARN);
loglevels.push_back(Debug::CRIT);
loglevels.push_back(Debug::LEVEL1);
loglevels.push_back(Debug::LEVEL2);
loglevels.push_back( Debug::type(Debug::LEVEL2 | Debug::INFO) );
loglevels.push_back( Debug::type(Debug::LEVEL2 | Debug::INFO | Debug::WARN | Debug::CRIT) );
lit = loglevels.begin();
out_log_c = (*lit);
vmonit(undef);
mbPort = 2048; // getId();
ost::InetAddress mbIAddr("localhost");
try
{
ost::Thread::setException(ost::Thread::throwException);
mbslave = make_shared<ModbusTCPServerSlot>(mbIAddr, mbPort);
mbslave->connectWriteSingleOutput( sigc::mem_fun(this, &TestProc::writeOutputSingleRegister) );
loga->add( mbslave->log() );
mbslave->log()->level(Debug::ANY);
mbthr = make_shared< ThreadCreator<TestProc> >(this, &TestProc::mbThread);
myinfo << myname << "(init) ModbusSlave " << mbIP << ":" << mbPort << endl;
}
catch( const ost::SockException& e )
{
ostringstream err;
err << myname << "(init) Can`t create socket " << mbIP << ":" << mbPort << " err: " << e.getString() << endl;
mycrit << err.str() << endl;
throw SystemError(err.str());
}
catch( const std::exception& ex )
{
mycrit << myname << "(init): " << ex.what() << endl;
throw ex;
}
}
// -----------------------------------------------------------------------------
TestProc::~TestProc()
{
}
// -----------------------------------------------------------------------------
TestProc::TestProc():
state(false)
{
cerr << ": init failed!!!!!!!!!!!!!!!" << endl;
throw Exception();
}
// -----------------------------------------------------------------------------
void TestProc::step()
{
}
// -----------------------------------------------------------------------------
void TestProc::sysCommand( const UniSetTypes::SystemMessage* sm )
{
TestProc_SK::sysCommand(sm);
if( sm->command == SystemMessage::StartUp || sm->command == SystemMessage::WatchDog )
{
askTimer(tmCheck, checkTime);
askTimer(tmCheckWorking, checkWorkingTime);
askTimer(tmLogControl, checkLogTime);
if( mbthr )
mbthr->start();
// В начальный момент времени блокирующий датчик =0, поэтому d2_check_s должен быть равен depend_off_value (-50).
cerr << myname << "(startup): check init depend: " << ( getValue(d2_check_s) == -50 ? "ok" : "FAIL" ) << endl;
}
}
// -----------------------------------------------------------------------------
void TestProc::sensorInfo( const SensorMessage* sm )
{
/*
mylog2 << myname << "(sensorInfo): id=" << sm->id << " val=" << sm->value
<< " " << timeToString(sm->sm_tv_sec,":")
<< "(" << setw(6) << sm->sm_tv_usec << "): "
<< endl;
*/
if( sm->id == on_s )
{
if( sm->value )
{
cerr << myname << "(sensorInfo): START WORKING.." << endl;
askTimer(tmChange, changeTime);
}
else
{
askTimer(tmChange, 0);
cerr << myname << "(sensorInfo): STOP WORKING.." << endl;
}
}
else if( sm->id == check_undef_s )
{
cerr << myname << "(sensorInfo): CHECK UNDEFINED STATE ==> " << (sm->undefined == undef ? "ok" : "FAIL") << endl;
}
}
// -----------------------------------------------------------------------------
void TestProc::timerInfo( const TimerMessage* tm )
{
if( tm->id == tmChange )
{
state ^= true;
out_lamp_c = ( state ? lmpBLINK : lmpOFF );
mylog2 << myname << ": state=" << state << " lmp=" << out_lamp_c << endl;
askTimer(tmCheckWorking, 0); // test remove timer
askTimer(tmCheckWorking, checkTime); // reset timer
}
else if( tm->id == tmCheckWorking )
cerr << myname << ": WORKING FAIL!" << endl;
else if( tm->id == tmCheck )
{
cerr << endl << endl << "--------" << endl;
test_depend();
test_undefined_state();
test_thresholds();
test_loglevel();
}
else if( tm->id == tmLogControl )
{
cerr << endl;
cerr << "======= TEST LOG PRINT ======" << endl;
cerr << "LOGLEVEL: [" << (int)(*lit) << "] " << (*lit) << endl;
for( auto& it : loglevels )
mylog->debug(it) << myname << ": test log print..." << endl;
cerr << "======= END LOG PRINT ======" << endl;
}
}
// -----------------------------------------------------------------------------
void TestProc::test_depend()
{
cerr << myname << ": Check depend..." << endl;
long test_val = 100;
// set depend 0...
setValue(depend_c, 0);
setValue(set_d1_check_s, test_val);
setValue(set_d2_check_s, test_val);
cerr << myname << ": check depend OFF: d1: " << ( getValue(d1_check_s) == 0 ? "ok" : "FAIL" ) << endl;
cerr << myname << ": check depend OFF: d2: " << ( getValue(d2_check_s) == -50 ? "ok" : "FAIL" ) << endl;
// set depend 1
setValue(depend_c, 1);
cerr << myname << ": check depend ON: d1: " << ( getValue(d1_check_s) == test_val ? "ok" : "FAIL" ) << endl;
cerr << myname << ": check depend ON: d2: " << ( getValue(d2_check_s) == test_val ? "ok" : "FAIL" ) << endl;
}
// -----------------------------------------------------------------------------
void TestProc::test_undefined_state()
{
// ---------------- Проверка выставления неопределённого состояния ---------------------
cerr << myname << ": Check undef state..." << endl;
undef ^= true;
si.id = undef_c;
si.node = uniset_conf()->getLocalNode();
cerr << myname << ": set undefined=" << undef << endl;
ui->setUndefinedState( si, undef, getId() );
}
// -----------------------------------------------------------------------------
void TestProc::test_thresholds()
{
// ---------------- Проверка работы порогов ---------------------
cerr << myname << ": Check thresholds..." << endl;
setValue(t_set_c, 0);
cerr << myname << ": check threshold OFF value: " << ( getValue(t_check_s) == 0 ? "ok" : "FAIL" ) << endl;
setValue(t_set_c, 378);
cerr << myname << ": check threshold ON value: " << ( getValue(t_check_s) == 1 ? "ok" : "FAIL" ) << endl;
cerr << myname << ": ask threshold and check.. " << endl;
try
{
setValue(t_set_c, 0);
UniSetTypes::ThresholdId tid = 100;
ui->askThreshold( t_set_c, tid, UniversalIO::UIONotify, 10, 20 );
IONotifyController_i::ThresholdInfo ti = ui->getThresholdInfo(t_set_c, tid);
cerr << myname << ": ask OFF threshold: " << ( ti.state == IONotifyController_i::NormalThreshold ? "ok" : "FAIL" ) << endl;
setValue(t_set_c, 25);
ti = ui->getThresholdInfo(t_set_c, tid);
cerr << myname << ": ask ON threshold: " << ( ti.state == IONotifyController_i::HiThreshold ? "ok" : "FAIL" ) << endl;
}
catch( const Exception& ex )
{
mylog2 << myname << ": CHECK 'ask and get threshold' FAILED: " << ex << endl;
}
}
// -----------------------------------------------------------------------------
void TestProc::test_loglevel()
{
lit++;
if( lit == loglevels.end() )
lit = loglevels.begin();
cerr << "SET LOGLEVEL: [" << (int)(*lit) << "] " << (*lit) << endl;
setValue(log_c, (*lit));
askTimer(tmLogControl, checkLogTime);
}
// -----------------------------------------------------------------------------
void TestProc::mbThread()
{
mylog9 << myname << "ModbusSlave started " << mbIP << ":" << mbPort << endl;
mylog9 << myname << "(mbThread): run tcpserver.." << endl;
ModbusRTU::ModbusAddr mba(mbADDR);
auto vaddr = mbslave->addr2vaddr(mba);
mbslave->run( vaddr, false ); // true - создаёт поток
mylog9 << myname << "ModbusSlave stopped.." << endl;
}
// -------------------------------------------------------------------------
ModbusRTU::mbErrCode TestProc::writeOutputSingleRegister( ModbusRTU::WriteSingleOutputMessage& query,
ModbusRTU::WriteSingleOutputRetMessage& reply )
{
mylog9 << myname << "(writeOutputSingleRegister): " << query << endl;
reply.set(query.start, query.data);
return ModbusRTU::erNoError;
}
// -----------------------------------------------------------------------------
#ifndef TestProc_H_
#define TestProc_H_
// -----------------------------------------------------------------------------
#include <vector>
#include "Debug.h"
#include "TestProc_SK.h"
#include "modbus/ModbusTCPServerSlot.h"
// -----------------------------------------------------------------------------
class TestProc:
public TestProc_SK
{
public:
TestProc( UniSetTypes::ObjectId id, xmlNode* confnode = UniSetTypes::uniset_conf()->getNode("TestProc") );
virtual ~TestProc();
protected:
TestProc();
enum Timers
{
tmChange,
tmCheckWorking,
tmCheck,
tmLogControl
};
virtual void step();
virtual void sensorInfo( const UniSetTypes::SensorMessage* sm );
virtual void timerInfo( const UniSetTypes::TimerMessage* tm );
virtual void sysCommand( const UniSetTypes::SystemMessage* sm );
void test_depend();
void test_undefined_state();
void test_thresholds();
void test_loglevel();
private:
bool state;
bool undef;
std::vector<Debug::type> loglevels;
std::vector<Debug::type>::iterator lit;
std::shared_ptr<ModbusTCPServerSlot> mbslave;
/*! обработка 0x06 */
ModbusRTU::mbErrCode writeOutputSingleRegister( ModbusRTU::WriteSingleOutputMessage& query,
ModbusRTU::WriteSingleOutputRetMessage& reply );
std::shared_ptr< ThreadCreator<TestProc> > mbthr;
void mbThread();
};
// -----------------------------------------------------------------------------
#endif // TestProc_H_
// -----------------------------------------------------------------------------
#include <string>
#include "Debug.h"
#include "UniSetActivator.h"
#include "SharedMemory.h"
#include "Extensions.h"
#include "TestProc.h"
// --------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// --------------------------------------------------------------------------
int main(int argc, const char** argv)
{
if( argc > 1 && ( strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0 ) )
{
cout << "--confile - Использовать указанный конф. файл. По умолчанию configure.xml" << endl;
SharedMemory::help_print(argc, argv);
return 0;
}
try
{
auto conf = uniset_init(argc, argv);
auto shm = SharedMemory::init_smemory(argc, argv);
if( !shm )
return 1;
auto act = UniSetActivator::Instance();
act->add(shm);
int num = conf->getArgPInt("--numproc", 1);
for( int i = 1; i <= num; i++ )
{
ostringstream s;
s << "TestProc" << i;
cout << "..create " << s.str() << endl;
auto tp = make_shared<TestProc>( conf->getObjectID(s.str()));
// tp->init_dlog(dlog());
act->add(tp);
}
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
act->run(false);
return 0;
}
catch( const SystemError& err )
{
ucrit << "(smemory): " << err << endl;
}
catch( const Exception& ex )
{
ucrit << "(smemory): " << ex << endl;
}
catch( const std::exception& e )
{
ucrit << "(smemory): " << e.what() << endl;
}
catch(...)
{
ucrit << "(smemory): catch(...)" << endl;
}
return 1;
}
#!/bin/sh
START=uniset2-start.sh
${START} -f ./mbslave-test --confile ./test.xml --dlog-add-levels level1 --localNode LocalhostNode \
--sm-log-add-levels any $* --sm-run-logserver --TestProc1-run-logserver
../../../Utilities/scripts/uniset2-stop.sh
\ No newline at end of file
../../../conf/test.xml
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
name - название класса
msgcount - сколько сообщений обрабатывается за один раз
sleep_msec - пауза между итерациями в работе процесса
type
====
in - входные регистры (только для чтения)
out - выходные регистры (запись)
-->
<TestProc>
<settings>
<set name="class-name" val="TestProc"/>
<set name="msg-count" val="30"/>
<set name="sleep-msec" val="150"/>
</settings>
<variables>
<item name="changeTime" type="int" default="2000" min="0" comment="change state time" const="1" public="1" />
<item name="checkWorkingTime" type="int" default="3000" min="0" comment="check working time" const="1" public="1" />
<item name="checkTime" type="int" default="3000" min="0" comment="check Working time" const="1" public="1" />
<item name="checkLogTime" type="int" default="2500" min="0" comment="Проверка управления логами" const="1" public="1" />
<item const="1" type="str" public="1" name="mbIP" comment="Modbus ip (slave)" default="localhost"/>
<item const="1" type="int" public="1" name="mbADDR" comment="Modbus slave addr (slave)" default="0x01"/>
<item type="int" public="1" name="mbPort" comment="Modbus port (slave)" default="502"/>
</variables>
<smap>
<!-- name - название переменной в конф. файле -->
<item name="on_s" vartype="in" comment="Тестовый вход" smTestID="1"/>
<item name="lamp_c" vartype="out" comment="Лампочка (тестовый выход)"/>
<!-- проверка работы механизма зависимостей -->
<item name="depend_c" vartype="out" comment="Датчик от которого зависит состояние другого"/>
<item name="d1_check_s" vartype="in" comment="состояние зависимого датчика"/>
<item name="d2_check_s" vartype="in" comment="состояние зависимого датчика"/>
<item name="set_d1_check_s" vartype="out" comment="для выставления датчика"/>
<item name="set_d2_check_s" vartype="out" comment="для выставления датчика"/>
<!-- проверка работы undefined state -->
<item name="undef_c" vartype="out" comment="аналоговый датчик (для проверки undef-состояния)"/>
<item name="check_undef_s" vartype="in" comment="датчик для выставления undef-состояния"/>
<!-- проверка работы threshold-ов -->
<item name="t_set_c" vartype="out" comment="аналоговый датчик (для выставления порога)"/>
<item name="t_check_s" vartype="in" comment="датчик для проверки срабатывания"/>
<!-- Проверка управления логами -->
<item name="log_c" vartype="out" comment="аналоговый датчик для выставления уровня логов"/>
<item name="log_s" vartype="in" comment="датчик для управления логами" loglevel="1"/>
</smap>
<msgmap>
</msgmap>
</TestProc>
../../../Utilities/scripts/uniset2-functions.sh
\ No newline at end of file
../../../Utilities/scripts/uniset2-start.sh
\ No newline at end of file
SUBDIR=SMemoryTest
SUBDIRS=SMemoryTest MBSlaveTest
if HAVE_TESTS
noinst_PROGRAMS = tests tests_with_conf tests_with_sm sm_perf_test
......
......@@ -16,7 +16,7 @@ namespace UTCPCore
// Buffer class - allow for output buffering such that it can be written out into async pieces
struct Buffer
{
unsigned char* data;
unsigned char* data = { 0 };
ssize_t len;
ssize_t pos;
......
......@@ -5,6 +5,7 @@
#include <unordered_map>
#include <type_traits>
#include <tuple>
#include "UTCPCore.h"
template<typename... Args>
class VMon
......@@ -19,6 +20,18 @@ using namespace std;
int main( int argc, const char** argv )
{
unsigned char dat[] = { '1', '2', '3' ,'4' };
// UTCPCore::Buffer* buf = new UTCPCore::Buffer( dat, 0 );
UTCPCore::Buffer* buf = new UTCPCore::Buffer( dat, 3 );
// if( buf->nbytes() == 0 )
// delete buf;
cout << "buf: " << buf->dpos() << endl;
delete buf;
// VMon<int,double,char> vmon;
// cout << std::get<0>(vmon.m_tuple).size() << endl;
......
......@@ -191,6 +191,12 @@ extensions/tests/SMemoryTest/test.xml
extensions/tests/SMemoryTest/TestProc.cc
extensions/tests/SMemoryTest/TestProc.h
extensions/tests/SMemoryTest/testproc.src.xml
extensions/tests/SMemoryTest/Makefile.am
extensions/tests/MBSlaveTest/mbslave-test.cc
extensions/tests/MBSlaveTest/test.xml
extensions/tests/MBSlaveTest/TestProc.cc
extensions/tests/MBSlaveTest/TestProc.h
extensions/tests/MBSlaveTest/testproc.src.xml
extensions/tests/Makefile.am
extensions/tests/test.xml
extensions/tests/test_calibration.cc
......
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