Commit 6c00d237 authored by Pavel Vainerman's avatar Pavel Vainerman

(SM): added undefined value for IOController

parent 4404d4a2
......@@ -50,6 +50,7 @@ interface IOController_i : UniSetManager_i
*/
exception Undefined
{
long value; // текущее значение (может быть специальным undefined_value)
};
/*! Информация о датчике */
......
......@@ -131,6 +131,9 @@
<item id="1064" mb="1" mbtype="rtu" mbaddr="0x01" mbreg="208" mbfunc="0x03" vtype="F2" iotype="AI" name="TestQueryOptimization5_F2" textname="F2: Тестовый регистр для 0x03"/>
<item id="1065" mb="1" mbtype="rtu" mbaddr="0x01" mbreg="210" mbfunc="0x03" vtype="F2" iotype="AI" name="TestQueryOptimization6_F2" textname="F2: Тестовый регистр для 0x03"/>
<!-- undefined state -->
<item id="1070" mb="1" mbtype="rtu" mbaddr="0x01" mbreg="240" mbfunc="0x03" default="150" undefined_value="65535" breaklim="100" name="UndefinedState_FS" iotype="AI" textname="Тестирование неопределённого состояния"/>
<item id="10000" iotype="DI" name="TestMode_S" textname="Тестовый датчик"/>
</sensors>
......
......@@ -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
......
......@@ -741,6 +741,31 @@ TEST_CASE("MBTCPMaster: safe mode (resetIfNotRespond)", "[modbus][safemode][mbma
REQUIRE( ui->getValue(1054) == 1 );
}
// -----------------------------------------------------------------------------
TEST_CASE("MBTCPMaster: udefined value", "[modbus][undefined][mbmaster][mbtcpmaster]")
{
InitTest();
mbs->setReply(120);
msleep(polltime + 200);
REQUIRE( ui->getValue(1070) == 120 );
mbs->setReply(10);
msleep(polltime + 200);
try
{
ui->getValue(1070);
}
catch( IOController_i::Undefined& ex )
{
REQUIRE( ex.value == 65535 );
}
mbs->setReply(120);
msleep(polltime + 200);
REQUIRE( ui->getValue(1070) == 120 );
}
// -----------------------------------------------------------------------------
#if 0
// -----------------------------------------------------------------------------
static bool init_iobase( IOBase* ib, const std::string& sensor )
......
......@@ -221,5 +221,35 @@ TEST_CASE("MBTCPMaster: safe mode (resetIfNotRespond)", "[modbus][safemode][mbma
msleep(5000);
REQUIRE( ui->getValue(1053) == 53 );
REQUIRE( ui->getValue(1054) == 1 );
mbs1->setReply(0);
mbs2->setReply(0);
}
// -----------------------------------------------------------------------------
TEST_CASE("MBTCPMaster: udefined value", "[modbus][undefined][mbmaster][mbtcpmaster]")
{
InitTest();
mbs1->setReply(120);
mbs2->setReply(120);
msleep(polltime + 200);
REQUIRE( ui->getValue(1070) == 120 );
mbs1->setReply(10);
mbs2->setReply(10);
msleep(polltime + 200);
try
{
ui->getValue(1070);
}
catch( IOController_i::Undefined& ex )
{
REQUIRE( ex.value == 65535 );
}
mbs1->setReply(120);
mbs2->setReply(120);
msleep(polltime + 200);
REQUIRE( ui->getValue(1070) == 120 );
}
// -----------------------------------------------------------------------------
......@@ -769,7 +769,8 @@ namespace uniset
}
catch( IOController_i::Undefined& ex )
{
hit.add( numeric_limits<long>::max(), it.size );
hit.add( ex.value, it.size );
// hit.add( numeric_limits<long>::max(), it.size );
}
catch(...) {}
}
......
......@@ -161,10 +161,8 @@ namespace uniset
catch( IOController_i::Undefined& ex )
{
unetwarn << myname << "(updateFromSM): sid=" << i.id
<< " undefined state..." << endl;
if( i.undefined_value != not_specified_value )
updateItem( i, i.undefined_value );
<< " undefined state (value=" << ex.value << ")." << endl;
updateItem( i, ex.value );
}
catch( std::exception& ex )
{
......
......@@ -56,7 +56,7 @@ void InitTest()
// -----------------------------------------------------------------------------
// pnum - минималный номер ожидаемого пакета ( 0 - любой пришедщий )
// ncycle - сколько пакетов разрешено "пропустить" прежде чем дождёмся нужного.. (чтобы не ждать бесконечно)
static UniSetUDP::UDPMessage receive( unsigned int pnum = 0, timeout_t tout = 2000, int ncycle = 10 )
static UniSetUDP::UDPMessage receive( unsigned int pnum = 0, timeout_t tout = 2000, int ncycle = 20 )
{
UniSetUDP::UDPMessage pack;
UniSetUDP::UDPPacket buf;
......@@ -76,6 +76,9 @@ static UniSetUDP::UDPMessage receive( unsigned int pnum = 0, timeout_t tout = 20
ncycle--;
}
// if( pnum > 0 && pack.num < pnum )
// return UniSetUDP::UDPMessage(); // empty message
return pack;
}
// -----------------------------------------------------------------------------
......@@ -300,7 +303,7 @@ TEST_CASE("[UNetUDP]: check receiver", "[unetudp][receiver]")
REQUIRE( ui->getValue(11) == 0 );
send(pack);
msleep(500);
msleep(600);
REQUIRE( ui->getValue(8) == 100 );
REQUIRE( ui->getValue(9) == -100 );
REQUIRE( ui->getValue(10) == 1 );
......@@ -318,7 +321,7 @@ TEST_CASE("[UNetUDP]: check receiver", "[unetudp][receiver]")
pack.addDData(10, false);
pack.addDData(11, true);
send(pack);
msleep(500);
msleep(600);
REQUIRE( ui->getValue(8) == 10 );
REQUIRE( ui->getValue(9) == -10 );
REQUIRE( ui->getValue(10) == 0 );
......@@ -472,12 +475,13 @@ TEST_CASE("[UNetUDP]: check undefined value", "[unetudp][sender]")
{
InitTest();
UniSetUDP::UDPMessage pack = receive();
UniSetUDP::UDPMessage pack0 = receive();
ui->setValue(2, 110);
REQUIRE( ui->getValue(2) == 110 );
msleep(600);
pack = receive();
UniSetUDP::UDPMessage pack = receive( pack0.num + 1, 2000, 40 );
REQUIRE( pack.num != 0 );
REQUIRE( pack.asize() == 4 );
......@@ -489,7 +493,7 @@ TEST_CASE("[UNetUDP]: check undefined value", "[unetudp][sender]")
si.node = uniset_conf()->getLocalNode();
ui->setUndefinedState(si, true, 6000 /* TestProc */ );
msleep(600);
pack = receive();
pack = receive(pack.num + 1);
REQUIRE( pack.num != 0 );
REQUIRE( pack.asize() == 4 );
......@@ -498,7 +502,7 @@ TEST_CASE("[UNetUDP]: check undefined value", "[unetudp][sender]")
ui->setUndefinedState(si, false, 6000 /* TestProc */ );
msleep(600);
pack = receive();
pack = receive(pack.num + 1);
REQUIRE( pack.num != 0 );
REQUIRE( pack.asize() == 4 );
......
......@@ -24,6 +24,7 @@
//---------------------------------------------------------------------------
#include <unordered_map>
#include <list>
#include <limits>
#include <sigc++/sigc++.h>
#include "IOController_i.hh"
#include "UniSetTypes.h"
......@@ -59,15 +60,14 @@ namespace uniset
virtual uniset::SimpleInfo* getInfo( const char* userparam = "" ) override;
// ----------------------------------------------------------------
// Публичный (IDL) интерфейс IOController_i
// ----------------------------------------------------------------
virtual CORBA::Long getValue( uniset::ObjectId sid ) override;
// -------------------- !!!!!!!!! ---------------------------------
// Реализуются конкретным i/o контроллером
// Не забывайте писать реализацию этих функций
virtual void setValue( uniset::ObjectId sid, CORBA::Long value,
uniset::ObjectId sup_id = uniset::DefaultObjectId ) override;
// ----------------------------------------------------------------
virtual void setUndefinedState( uniset::ObjectId sid,
CORBA::Boolean undefined,
uniset::ObjectId sup_id = uniset::DefaultObjectId ) override;
......@@ -116,6 +116,8 @@ namespace uniset
struct USensorInfo;
typedef std::unordered_map<uniset::ObjectId, std::shared_ptr<USensorInfo>> IOStateList;
static const long not_specified_value = { std::numeric_limits<long>::max() };
// ================== Достпуные сигналы =================
/*!
// \warning В сигнале напрямую передаётся указатель на внутреннюю структуру!
......@@ -330,6 +332,8 @@ namespace uniset
size_t nchanges = { 0 }; // количество изменений датчика
long undef_value = { not_specified_value }; // значение для "неопределённого состояния датчика"
// функция обработки информации об изменении состояния датчика, от которого зависит данный
void checkDepend( std::shared_ptr<USensorInfo>& d_usi, IOController* );
......
......@@ -213,6 +213,9 @@ namespace uniset
inf->undefined = false;
inf->real_value = inf->value;
if( !it.getProp("undefined_value").empty() )
inf->undef_value = it.getIntProp("undefined_value");
string d_txt( it.getProp("depend") );
if( !d_txt.empty() )
......
......@@ -163,7 +163,11 @@ long IOController::localGetValue( std::shared_ptr<USensorInfo>& usi )
uniset_rwmutex_rlock lock(usi->val_lock);
if( usi->undefined )
throw IOController_i::Undefined();
{
auto ex = IOController_i::Undefined();
ex.value = usi->value;
throw ex;
}
return usi->value;
}
......@@ -198,10 +202,19 @@ void IOController::localSetUndefinedState( IOStateList::iterator& li,
bool changed = false;
{
auto usi = li->second;
// lock
uniset_rwmutex_wrlock lock(li->second->val_lock);
changed = (li->second->undefined != undefined);
li->second->undefined = undefined;
uniset_rwmutex_wrlock lock(usi->val_lock);
changed = (usi->undefined != undefined);
usi->undefined = undefined;
if( usi->undef_value != not_specified_value )
{
if( undefined )
usi->value = usi->undef_value;
else
usi->value = usi->real_value;
}
} // unlock
// сперва локальные события...
......
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