Commit 2e01bbf4 authored by Pavel Vainerman's avatar Pavel Vainerman Committed by Pavel Vainerman

added support "freeze value"

parent a9921db2
......@@ -69,6 +69,9 @@ interface IOController_i : UniSetManager_i
void setUndefinedState(in uniset::ObjectId sid, in boolean undefined, in uniset::ObjectId sup_id )
raises(NameNotFound);
// "заморозка"/"разморозка" значения. set=true - выставить value и не менять, пока не будет вызван set=false
void freezeValue(in uniset::ObjectId sid, in boolean set, in long value, in uniset::ObjectId sup_id ) raises(NameNotFound);
UniversalIO::IOType getIOType(in uniset::ObjectId sid) raises(NameNotFound);
// --- Интерфейс для конфигурирования ---
......@@ -95,7 +98,8 @@ interface IOController_i : UniSetManager_i
long value; /*!< значение */
boolean undefined; /*!< признак неопределённости значения */
boolean blocked; /*!< данное значение блокировано другим */
long real_value; /*!< запомненное состояние, до блокировки */
boolean frozen; /*!< данное значение "заморожено" */
long real_value; /*!< запомненное состояние, до блокировки или заморозки */
UniversalIO::IOType type; /*!< тип */
long priority; /*!< приоритет уведомления */
IOController_i::SensorInfo si;
......
......@@ -56,6 +56,7 @@ static struct option longopts[] =
{ "quiet", no_argument, 0, 'q' },
{ "csv", required_argument, 0, 'z' },
{ "sendText", required_argument, 0, 'm' },
{ "freezeValue", required_argument, 0, 'n' },
{ NULL, 0, 0, 0 }
};
......@@ -79,6 +80,7 @@ int getCalibrate( const string& args, UInterface& ui );
int oinfo(const string& args, UInterface& ui, const string& userparam );
int apiRequest( const string& args, UInterface& ui, const string& query );
void sendText( const string& args, UInterface& ui, const string& txt, int mtype );
int freezeValue( const string& args, bool set, UInterface& ui );
// --------------------------------------------------------------------------
static void print_help(int width, const string& cmd, const string& help, const string& tab = " " )
{
......@@ -126,6 +128,7 @@ static void usage()
print_help(36, "-q|--quiet", "Выводит только результат.\n");
print_help(36, "-z|--csv", "Вывести результат (getValue) в виде val1,val2,val3...\n");
print_help(36, "-m|--sendText id1@node1,id2@node2,id3,.. mtype text", "Послать объектам текстовое сообщение text типа mtype\n");
print_help(36, "-n|--freezeValue id1@node1=val1,id2@node2=val2,id3=val3,.. set", "Выставить указанным датчикам соответствующие значения и заморозить их (set=true) или разморозить (set=false).\n");
cout << endl;
}
......@@ -199,6 +202,26 @@ int main(int argc, char** argv)
}
break;
case 'n': //--freezeValue
{
// смотрим второй параметр
if( checkArg(optind, argc, argv) == 0 )
{
if( !quiet )
cerr << "admin(freezeValue): Unknown 'set'. Use: id=v1,name=v2,name2@nodeX=v3 set" << endl;
return 1;
}
std::string sensors(optarg);
bool set = uni_atoi(argv[optind]);
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(uniset::AdminID);
return freezeValue(sensors, set, ui);
}
break;
case 'g': //--getValue
case 'z': //--csv
{
......@@ -810,6 +833,68 @@ int getValue( const string& args, UInterface& ui )
return err;
}
// --------------------------------------------------------------------------------------
int freezeValue( const string& args, bool set, UInterface& ui )
{
int err = 0;
auto conf = ui.getConf();
auto sl = uniset::getSInfoList(args, conf);
if( verb )
cout << "====== freezeValue ======" << endl;
for( auto&& it : sl )
{
try
{
UniversalIO::IOType t = conf->getIOType(it.si.id);
if( verb )
{
cout << " value: " << it.val << endl;
cout << " name: (" << it.si.id << ") " << it.fname << endl;
cout << " iotype: " << t << endl;
cout << " text: " << conf->oind->getTextName(it.si.id) << "\n\n";
}
if( it.si.node == DefaultObjectId )
it.si.node = conf->getLocalNode();
switch(t)
{
case UniversalIO::DI:
case UniversalIO::DO:
case UniversalIO::AI:
case UniversalIO::AO:
ui.freezeValue(it.si, set, it.val, AdminID);
break;
default:
if( !quiet )
cerr << "FAILED: Unknown 'iotype' for " << it.fname << endl;
err = 1;
break;
}
}
catch( const uniset::Exception& ex )
{
if( !quiet )
cerr << "(setValue): " << ex << endl;;
err = 1;
}
catch( const std::exception& ex )
{
if( !quiet )
cerr << "std::exception: " << ex.what() << endl;
err = 1;
}
}
return err;
}
// --------------------------------------------------------------------------------------
int getCalibrate( const std::string& args, UInterface& ui )
{
int err = 0;
......
......@@ -19,6 +19,7 @@ ln -s -f admin.sh help
ln -s -f admin.sh oinfo
ln -s -f admin.sh apiRequest
ln -s -f admin.sh sendText
ln -s -f admin.sh freezeValue
ln -s -f ../../Utilities/scripts/uniset2-start.sh
ln -s -f ../../Utilities/scripts/uniset2-stop.sh stop.sh
......
......@@ -30,7 +30,7 @@
<item node="localhost" name="ReservSharedMemory"/>
</ReservList>
</SharedMemory>
<TestObject name="TestObject" sensor_s="DI2_S" output_c="AO2_C" dependDI_s="DependDI_S" dependAI_s="DependAI_S" monotonic_s="MonotonicAI_S" heartbeat_id="TO_Heartbeat_Counter" heartbeatTime="500" heartbeat_max="5"/>
<TestObject name="TestObject" sensor_s="DI2_S" output_c="AO2_C" dependDI_s="DependDI_S" dependAI_s="DependAI_S" monotonic_s="MonotonicAI_S" freeze_s="FreezeAI_S" heartbeat_id="TO_Heartbeat_Counter" heartbeatTime="500" heartbeat_max="5"/>
</settings>
<ObjectsMap idfromfile="1">
<nodes port="2809" unet_broadcast_ip="192.168.1.255" unet_broadcast_ip2="192.168.122.255">
......@@ -56,6 +56,8 @@
<item id="514" iotype="DI" name="Depend_BlockSensor_S" priority="Medium" textname="Block Sensor for depend"/>
<item id="515" iotype="DI" name="Threshold2_S" priority="Medium" textname="Threshold 2"/>
<item id="516" iotype="AI" name="MonotonicAI_S" priority="Medium" textname="monitonic AI"/>
<item id="517" iotype="AI" name="FreezeAI_S" priority="Medium" textname="Freeze AI sesnor"/>
</sensors>
<thresholds name="thresholds">
<sensor name="AI1_AS">
......
......@@ -323,3 +323,32 @@ TEST_CASE("[SM]: sendText", "[sm][sendText]")
REQUIRE( obj->getLastTextMessage() == txt );
REQUIRE( obj->getLastTextMessageType() == 3 );
}
// -----------------------------------------------------------------------------
TEST_CASE("[SM]: freezeValue", "[sm][freezeValue]")
{
InitTest();
IOController_i::SensorInfo si;
si.id = 517;
si.node = uniset_conf()->getLocalNode();
REQUIRE_NOTHROW( ui->setValue(517, 100) );
REQUIRE( ui->getValue(517) == 100 );
msleep(300);
REQUIRE( obj->in_freeze_s == 100 );
REQUIRE_NOTHROW( ui->freezeValue(si, true, 10) );
REQUIRE( ui->getValue(517) == 10 );
msleep(300);
REQUIRE( obj->in_freeze_s == 10 );
REQUIRE_NOTHROW( ui->setValue(517, 150) );
REQUIRE( ui->getValue(517) == 10 );
msleep(300);
REQUIRE( obj->in_freeze_s == 10 );
REQUIRE_NOTHROW( ui->freezeValue(si, false, 10) );
REQUIRE( ui->getValue(517) == 150 );
msleep(300);
REQUIRE( obj->in_freeze_s == 150 );
}
......@@ -13,6 +13,7 @@
<item name="dependDI_s" vartype="in" iotype="DI" comment="Test input"/>
<item name="dependAI_s" vartype="in" iotype="AI" comment="Test input"/>
<item name="monotonic_s" vartype="in" iotype="AI" comment="Test analog input"/>
<item name="freeze_s" vartype="in" iotype="AI" comment="Test freeze input"/>
</smap>
<msgmap>
......
#include <catch.hpp>
#include <memory>
#include <time.h>
#include "IOController_i.hh"
#include "UInterface.h"
......@@ -8,122 +9,130 @@
using namespace std;
using namespace uniset;
TEST_CASE("UInterface", "[UInterface]")
const std::string sidName = "Input1_S";
const std::string aidName = "AI_AS";
ObjectId testOID;
ObjectId sid;
ObjectId aid;
std::shared_ptr<UInterface> ui;
void init()
{
CHECK( uniset_conf() != nullptr );
std::string sidName("Input1_S");
std::string aidName("AI_AS");
auto conf = uniset_conf();
ObjectId testOID = conf->getObjectID("TestProc");
testOID = conf->getObjectID("TestProc");
CHECK( testOID != DefaultObjectId );
ObjectId sid = conf->getSensorID(sidName);
sid = conf->getSensorID(sidName);
CHECK( sid != DefaultObjectId );
ObjectId aid = conf->getSensorID(aidName);
aid = conf->getSensorID(aidName);
CHECK( aid != DefaultObjectId );
UInterface ui;
if( ui == nullptr )
ui = std::make_shared<UInterface>();
CHECK( ui.getObjectIndex() != nullptr );
CHECK( ui.getConf() == uniset_conf() );
CHECK( ui->getObjectIndex() != nullptr );
CHECK( ui->getConf() == uniset_conf() );
REQUIRE( ui.getConfIOType(sid) == UniversalIO::DI );
REQUIRE( ui.getConfIOType(aid) == UniversalIO::AI );
// REQUIRE( ui.getType(sid) == "IONotifyController" );
// REQUIRE( ui.getType(aid) == "IONotifyController" );
REQUIRE( ui->getConfIOType(sid) == UniversalIO::DI );
REQUIRE( ui->getConfIOType(aid) == UniversalIO::AI );
}
TEST_CASE("UInterface", "[UInterface]")
{
init();
auto conf = uniset_conf();
SECTION( "GET/SET" )
{
REQUIRE_THROWS_AS( ui.getValue(DefaultObjectId), uniset::ORepFailed );
REQUIRE_NOTHROW( ui.setValue(sid, 1) );
REQUIRE( ui.getValue(sid) == 1 );
REQUIRE_NOTHROW( ui.setValue(sid, 100) );
REQUIRE( ui.getValue(sid) == 100 ); // хоть это и дискретный датчик.. функция-то универсальная..
REQUIRE_THROWS_AS( ui->getValue(DefaultObjectId), uniset::ORepFailed );
REQUIRE_NOTHROW( ui->setValue(sid, 1) );
REQUIRE( ui->getValue(sid) == 1 );
REQUIRE_NOTHROW( ui->setValue(sid, 100) );
REQUIRE( ui->getValue(sid) == 100 ); // хоть это и дискретный датчик.. функция-то универсальная..
REQUIRE_THROWS_AS( ui.getValue(sid, DefaultObjectId), uniset::Exception );
REQUIRE_THROWS_AS( ui.getValue(sid, 100), uniset::Exception );
REQUIRE_THROWS_AS( ui->getValue(sid, DefaultObjectId), uniset::Exception );
REQUIRE_THROWS_AS( ui->getValue(sid, 100), uniset::Exception );
REQUIRE_NOTHROW( ui.setValue(aid, 10) );
REQUIRE( ui.getValue(aid) == 10 );
REQUIRE_NOTHROW( ui->setValue(aid, 10) );
REQUIRE( ui->getValue(aid) == 10 );
IOController_i::SensorInfo si;
si.id = aid;
si.node = conf->getLocalNode();
REQUIRE_NOTHROW( ui.setValue(si, 15, DefaultObjectId) );
REQUIRE( ui.getRawValue(si) == 15 );
REQUIRE_NOTHROW( ui->setValue(si, 15, DefaultObjectId) );
REQUIRE( ui->getRawValue(si) == 15 );
REQUIRE_NOTHROW( ui.fastSetValue(si, 20, DefaultObjectId) );
REQUIRE( ui.getValue(aid) == 20 );
REQUIRE_THROWS_AS( ui.getValue(aid, -2), uniset::Exception );
REQUIRE_NOTHROW( ui->fastSetValue(si, 20, DefaultObjectId) );
REQUIRE( ui->getValue(aid) == 20 );
REQUIRE_THROWS_AS( ui->getValue(aid, -2), uniset::Exception );
si.id = sid;
REQUIRE_NOTHROW( ui.setValue(si, 15, DefaultObjectId) );
REQUIRE( ui.getValue(sid) == 15 );
REQUIRE_NOTHROW( ui->setValue(si, 15, DefaultObjectId) );
REQUIRE( ui->getValue(sid) == 15 );
si.node = -2;
REQUIRE_THROWS_AS( ui.setValue(si, 20, DefaultObjectId), uniset::Exception );
REQUIRE_THROWS_AS( ui->setValue(si, 20, DefaultObjectId), uniset::Exception );
REQUIRE_THROWS_AS( ui.getTimeChange(sid, DefaultObjectId), uniset::ORepFailed );
REQUIRE_NOTHROW( ui.getTimeChange(sid, conf->getLocalNode()) );
REQUIRE_THROWS_AS( ui->getTimeChange(sid, DefaultObjectId), uniset::ORepFailed );
REQUIRE_NOTHROW( ui->getTimeChange(sid, conf->getLocalNode()) );
si.id = aid;
si.node = conf->getLocalNode();
REQUIRE_NOTHROW( ui.setUndefinedState(si, true, testOID) );
REQUIRE_NOTHROW( ui.setUndefinedState(si, false, testOID) );
REQUIRE_NOTHROW( ui->setUndefinedState(si, true, testOID) );
REQUIRE_NOTHROW( ui->setUndefinedState(si, false, testOID) );
si.id = sid;
si.node = conf->getLocalNode();
REQUIRE_NOTHROW( ui.setUndefinedState(si, true, testOID) );
REQUIRE_NOTHROW( ui.setUndefinedState(si, false, testOID) );
REQUIRE_NOTHROW( ui->setUndefinedState(si, true, testOID) );
REQUIRE_NOTHROW( ui->setUndefinedState(si, false, testOID) );
REQUIRE( ui.getIOType(sid, conf->getLocalNode()) == UniversalIO::DI );
REQUIRE( ui.getIOType(aid, conf->getLocalNode()) == UniversalIO::AI );
REQUIRE( ui->getIOType(sid, conf->getLocalNode()) == UniversalIO::DI );
REQUIRE( ui->getIOType(aid, conf->getLocalNode()) == UniversalIO::AI );
}
SECTION( "resolve" )
{
REQUIRE_NOTHROW( ui.resolve(sid) );
REQUIRE_THROWS_AS( ui.resolve(sid, 10), uniset::ResolveNameError );
REQUIRE_THROWS_AS( ui.resolve(sid, DefaultObjectId), uniset::ResolveNameError );
REQUIRE_NOTHROW( ui->resolve(sid) );
REQUIRE_THROWS_AS( ui->resolve(sid, 10), uniset::ResolveNameError );
REQUIRE_THROWS_AS( ui->resolve(sid, DefaultObjectId), uniset::ResolveNameError );
}
SECTION( "send" )
{
TransportMessage tm( SensorMessage(sid, 10).transport_msg() );
REQUIRE_NOTHROW( ui.send(sid, tm) );
REQUIRE_NOTHROW( ui->send(sid, tm) );
}
SECTION( "sendText" )
{
TransportMessage tm( SensorMessage(sid, 10).transport_msg() );
REQUIRE_NOTHROW( ui.send(sid, tm) );
REQUIRE_NOTHROW( ui->send(sid, tm) );
}
SECTION( "wait..exist.." )
{
CHECK( ui.waitReady(sid, 200, 50) );
CHECK( ui.waitReady(sid, 200, 50, conf->getLocalNode()) );
CHECK_FALSE( ui.waitReady(sid, 300, 50, DefaultObjectId) );
CHECK_FALSE( ui.waitReady(sid, 300, 50, -20) );
CHECK_FALSE( ui.waitReady(sid, -1, 50) );
CHECK( ui.waitReady(sid, 300, -1) );
CHECK( ui.waitWorking(sid, 200, 50) );
CHECK( ui.waitWorking(sid, 200, 50, conf->getLocalNode()) );
CHECK_FALSE( ui.waitWorking(sid, 100, 50, DefaultObjectId) );
CHECK_FALSE( ui.waitWorking(sid, 100, 50, -20) );
CHECK_FALSE( ui.waitWorking(sid, -1, 50) );
CHECK( ui.waitWorking(sid, 100, -1) );
CHECK( ui.isExist(sid) );
CHECK( ui.isExist(sid, conf->getLocalNode()) );
CHECK_FALSE( ui.isExist(sid, DefaultObjectId) );
CHECK_FALSE( ui.isExist(sid, 100) );
CHECK( ui->waitReady(sid, 200, 50) );
CHECK( ui->waitReady(sid, 200, 50, conf->getLocalNode()) );
CHECK_FALSE( ui->waitReady(sid, 300, 50, DefaultObjectId) );
CHECK_FALSE( ui->waitReady(sid, 300, 50, -20) );
CHECK_FALSE( ui->waitReady(sid, -1, 50) );
CHECK( ui->waitReady(sid, 300, -1) );
CHECK( ui->waitWorking(sid, 200, 50) );
CHECK( ui->waitWorking(sid, 200, 50, conf->getLocalNode()) );
CHECK_FALSE( ui->waitWorking(sid, 100, 50, DefaultObjectId) );
CHECK_FALSE( ui->waitWorking(sid, 100, 50, -20) );
CHECK_FALSE( ui->waitWorking(sid, -1, 50) );
CHECK( ui->waitWorking(sid, 100, -1) );
CHECK( ui->isExist(sid) );
CHECK( ui->isExist(sid, conf->getLocalNode()) );
CHECK_FALSE( ui->isExist(sid, DefaultObjectId) );
CHECK_FALSE( ui->isExist(sid, 100) );
}
SECTION( "get/set list" )
......@@ -133,7 +142,7 @@ TEST_CASE("UInterface", "[UInterface]")
lst.add(sid);
lst.add(-100); // bad sensor ID
IOController_i::SensorInfoSeq_var seq = ui.getSensorSeq(lst);
IOController_i::SensorInfoSeq_var seq = ui->getSensorSeq(lst);
REQUIRE( seq->length() == 3 );
IOController_i::OutSeq_var olst = new IOController_i::OutSeq();
......@@ -145,71 +154,71 @@ TEST_CASE("UInterface", "[UInterface]")
olst[1].si.node = conf->getLocalNode();
olst[1].value = 35;
uniset::IDSeq_var iseq = ui.setOutputSeq(olst, DefaultObjectId);
uniset::IDSeq_var iseq = ui->setOutputSeq(olst, DefaultObjectId);
REQUIRE( iseq->length() == 0 );
IOController_i::ShortMapSeq_var slist = ui.getSensors( sid, conf->getLocalNode() );
IOController_i::ShortMapSeq_var slist = ui->getSensors( sid, conf->getLocalNode() );
REQUIRE( slist->length() >= 2 );
}
SECTION( "ask" )
{
REQUIRE_THROWS_AS( ui.askSensor(sid, UniversalIO::UIONotify), uniset::IOBadParam );
REQUIRE_NOTHROW( ui.askSensor(sid, UniversalIO::UIONotify, testOID) );
REQUIRE_NOTHROW( ui.askSensor(aid, UniversalIO::UIONotify, testOID) );
REQUIRE_NOTHROW( ui.askSensor(aid, UniversalIO::UIODontNotify, testOID) );
REQUIRE_NOTHROW( ui.askSensor(sid, UniversalIO::UIODontNotify, testOID) );
REQUIRE_THROWS_AS( ui->askSensor(sid, UniversalIO::UIONotify), uniset::IOBadParam );
REQUIRE_NOTHROW( ui->askSensor(sid, UniversalIO::UIONotify, testOID) );
REQUIRE_NOTHROW( ui->askSensor(aid, UniversalIO::UIONotify, testOID) );
REQUIRE_NOTHROW( ui->askSensor(aid, UniversalIO::UIODontNotify, testOID) );
REQUIRE_NOTHROW( ui->askSensor(sid, UniversalIO::UIODontNotify, testOID) );
REQUIRE_THROWS_AS( ui.askSensor(-20, UniversalIO::UIONotify), uniset::Exception );
REQUIRE_THROWS_AS( ui->askSensor(-20, UniversalIO::UIONotify), uniset::Exception );
REQUIRE_NOTHROW( ui.askRemoteSensor(sid, UniversalIO::UIONotify, conf->getLocalNode(), testOID) );
REQUIRE_NOTHROW( ui.askRemoteSensor(aid, UniversalIO::UIONotify, conf->getLocalNode(), testOID) );
REQUIRE_THROWS_AS( ui.askRemoteSensor(sid, UniversalIO::UIONotify, -3, testOID), uniset::Exception );
REQUIRE_NOTHROW( ui->askRemoteSensor(sid, UniversalIO::UIONotify, conf->getLocalNode(), testOID) );
REQUIRE_NOTHROW( ui->askRemoteSensor(aid, UniversalIO::UIONotify, conf->getLocalNode(), testOID) );
REQUIRE_THROWS_AS( ui->askRemoteSensor(sid, UniversalIO::UIONotify, -3, testOID), uniset::Exception );
uniset::IDList lst;
lst.add(aid);
lst.add(sid);
lst.add(-100); // bad sensor ID
uniset::IDSeq_var rseq = ui.askSensorsSeq(lst, UniversalIO::UIONotify, testOID);
uniset::IDSeq_var rseq = ui->askSensorsSeq(lst, UniversalIO::UIONotify, testOID);
REQUIRE( rseq->length() == 1 ); // проверяем, что нам вернули один BAD-датчик..(-100)
}
SECTION( "Thresholds" )
{
REQUIRE_NOTHROW( ui.askThreshold(aid, 10, UniversalIO::UIONotify, 90, 100, false, testOID) );
REQUIRE_NOTHROW( ui.askThreshold(aid, 11, UniversalIO::UIONotify, 50, 70, false, testOID) );
REQUIRE_NOTHROW( ui.askThreshold(aid, 12, UniversalIO::UIONotify, 20, 40, false, testOID) );
REQUIRE_THROWS_AS( ui.askThreshold(aid, 3, UniversalIO::UIONotify, 50, 20, false, testOID), IONotifyController_i::BadRange );
REQUIRE_NOTHROW( ui->askThreshold(aid, 10, UniversalIO::UIONotify, 90, 100, false, testOID) );
REQUIRE_NOTHROW( ui->askThreshold(aid, 11, UniversalIO::UIONotify, 50, 70, false, testOID) );
REQUIRE_NOTHROW( ui->askThreshold(aid, 12, UniversalIO::UIONotify, 20, 40, false, testOID) );
REQUIRE_THROWS_AS( ui->askThreshold(aid, 3, UniversalIO::UIONotify, 50, 20, false, testOID), IONotifyController_i::BadRange );
IONotifyController_i::ThresholdsListSeq_var slist = ui.getThresholdsList(aid);
IONotifyController_i::ThresholdsListSeq_var slist = ui->getThresholdsList(aid);
REQUIRE( slist->length() == 1 ); // количество датчиков с порогами = 1 (это aid)
// 3 порога мы создали выше(askThreshold) + 1 который в настроечном файле в секции <thresholds>
REQUIRE( slist[0].tlist.length() == 4 );
IONotifyController_i::ThresholdInfo ti1 = ui.getThresholdInfo(aid, 10);
IONotifyController_i::ThresholdInfo ti1 = ui->getThresholdInfo(aid, 10);
REQUIRE( ti1.id == 10 );
REQUIRE( ti1.lowlimit == 90 );
REQUIRE( ti1.hilimit == 100 );
IONotifyController_i::ThresholdInfo ti2 = ui.getThresholdInfo(aid, 11);
IONotifyController_i::ThresholdInfo ti2 = ui->getThresholdInfo(aid, 11);
REQUIRE( ti2.id == 11 );
REQUIRE( ti2.lowlimit == 50 );
REQUIRE( ti2.hilimit == 70 );
IONotifyController_i::ThresholdInfo ti3 = ui.getThresholdInfo(aid, 12);
IONotifyController_i::ThresholdInfo ti3 = ui->getThresholdInfo(aid, 12);
REQUIRE( ti3.id == 12 );
REQUIRE( ti3.lowlimit == 20 );
REQUIRE( ti3.hilimit == 40 );
REQUIRE_THROWS_AS( ui.getThresholdInfo(sid, 10), uniset::NameNotFound );
REQUIRE_THROWS_AS( ui->getThresholdInfo(sid, 10), uniset::NameNotFound );
// проверяем thresholds который был сформирован из секции <thresholds>
ui.setValue(10, 378);
REQUIRE( ui.getValue(13) == 1 );
ui.setValue(10, 0);
REQUIRE( ui.getValue(13) == 0 );
ui->setValue(10, 378);
REQUIRE( ui->getValue(13) == 1 );
ui->setValue(10, 0);
REQUIRE( ui->getValue(13) == 0 );
}
SECTION( "calibration" )
......@@ -224,9 +233,9 @@ TEST_CASE("UInterface", "[UInterface]")
ci.minCal = -100;
ci.maxCal = 100;
ci.precision = 3;
REQUIRE_NOTHROW( ui.calibrate(si, ci) );
REQUIRE_NOTHROW( ui->calibrate(si, ci) );
IOController_i::CalibrateInfo ci2 = ui.getCalibrateInfo(si);
IOController_i::CalibrateInfo ci2 = ui->getCalibrateInfo(si);
CHECK( ci.minRaw == ci2.minRaw );
CHECK( ci.maxRaw == ci2.maxRaw );
CHECK( ci.minCal == ci2.minCal );
......@@ -235,3 +244,29 @@ TEST_CASE("UInterface", "[UInterface]")
}
}
// -----------------------------------------------------------------------------
TEST_CASE("UInterface::freezeValue", "[UInterface][freezeValue]")
{
init();
auto conf = uniset_conf();
IOController_i::SensorInfo si;
si.id = aid;
si.node = conf->getLocalNode();
REQUIRE_NOTHROW( ui->freezeValue(si, true, 10, testOID) );
REQUIRE( ui->getValue(aid) == 10 );
REQUIRE_NOTHROW( ui->setValue(aid, 100) );
REQUIRE( ui->getValue(aid) == 10 );
REQUIRE_NOTHROW( ui->freezeValue(si, false, 10, testOID) );
REQUIRE( ui->getValue(aid) == 100 );
REQUIRE_NOTHROW( ui->freezeValue(si, true, -1, testOID) );
REQUIRE( ui->getValue(aid) == -1 );
REQUIRE_NOTHROW( ui->freezeValue(si, false, -1, testOID) );
REQUIRE( ui->getValue(aid) == 100 );
REQUIRE_NOTHROW( ui->setValue(aid, 200) );
REQUIRE( ui->getValue(aid) == 200 );
}
......@@ -72,6 +72,10 @@ namespace uniset
CORBA::Boolean undefined,
uniset::ObjectId sup_id = uniset::DefaultObjectId ) override;
virtual void freezeValue( uniset::ObjectId sid,
CORBA::Boolean set,
CORBA::Long value,
uniset::ObjectId sup_id = uniset::DefaultObjectId ) override;
virtual IOController_i::SensorInfoSeq* getSensorSeq( const uniset::IDSeq& lst ) override;
virtual uniset::IDSeq* setOutputSeq( const IOController_i::OutSeq& lst, uniset::ObjectId sup_id ) override;
......@@ -178,6 +182,16 @@ namespace uniset
// -- работа через указатель ---
virtual long localSetValue( std::shared_ptr<USensorInfo>& usi, CORBA::Long value, uniset::ObjectId sup_id );
long localGetValue( std::shared_ptr<USensorInfo>& usi) ;
virtual void localFreezeValueIt( IOController::IOStateList::iterator& li,
uniset::ObjectId sid,
CORBA::Boolean set,
CORBA::Long value,
uniset::ObjectId sup_id );
virtual void localFreezeValue( std::shared_ptr<USensorInfo>& usi,
CORBA::Boolean set,
CORBA::Long value,
uniset::ObjectId sup_id );
#ifndef DISABLE_REST_API
// http API
......
......@@ -39,7 +39,6 @@
// -----------------------------------------------------------------------------------------
namespace uniset
{
/*!
* \class UInterface
* Универсальный интерфейс для взаимодействия между объектами (процессами).
......@@ -99,6 +98,8 @@ namespace uniset
// установка неопределённого состояния
void setUndefinedState( const IOController_i::SensorInfo& si, bool undefined, uniset::ObjectId supplier );
// заморозка значения (выставить указанный value и не менять)
void freezeValue( const IOController_i::SensorInfo& si, bool set, long value, uniset::ObjectId supplier = uniset::DefaultObjectId );
// ---------------------------------------------------------------
// Калибровка... пороги...
......
......@@ -277,6 +277,81 @@ namespace uniset
uwarn << set_err("UI(setUndefinedState): Timeout", si.id, si.node) << endl;
}
// ------------------------------------------------------------------------------------------------------------
void UInterface::freezeValue( const IOController_i::SensorInfo& si, bool set, long value, uniset::ObjectId sup_id )
{
if( si.id == uniset::DefaultObjectId )
{
uwarn << "UI(freezeValue): ID=uniset::DefaultObjectId" << endl;
return;
}
if( sup_id == uniset::DefaultObjectId )
sup_id = myid;
try
{
CORBA::Object_var oref;
try
{
oref = rcache.resolve(si.id, si.node);
}
catch( const uniset::NameNotFound& ) {}
for (size_t i = 0; i < uconf->getRepeatCount(); i++)
{
try
{
if( CORBA::is_nil(oref) )
oref = resolve( si.id, si.node );
IOController_i_var iom = IOController_i::_narrow(oref);
iom->freezeValue(si.id, set, value, sup_id );
return;
}
catch( const CORBA::TRANSIENT& ) {}
catch( const CORBA::OBJECT_NOT_EXIST& ) {}
catch( const CORBA::SystemException& ex ) {}
msleep(uconf->getRepeatTimeout());
oref = CORBA::Object::_nil();
}
}
catch( const uniset::TimeOut& ) {}
catch(const IOController_i::NameNotFound& ex)
{
rcache.erase(si.id, si.node);
uwarn << set_err("UI(freezeValue):" + string(ex.err), si.id, si.node) << endl;
}
catch(const IOController_i::IOBadParam& ex)
{
rcache.erase(si.id, si.node);
throw uniset::IOBadParam("UI(freezeValue): " + string(ex.err));
}
catch(const uniset::ORepFailed& )
{
rcache.erase(si.id, si.node);
// не смогли получить ссылку на объект
uwarn << set_err("UI(freezeValue): resolve failed", si.id, si.node) << endl;
}
catch(const CORBA::NO_IMPLEMENT& )
{
rcache.erase(si.id, si.node);
uwarn << set_err("UI(freezeValue): method no implement", si.id, si.node) << endl;
}
catch( const CORBA::OBJECT_NOT_EXIST& )
{
rcache.erase(si.id, si.node);
uwarn << set_err("UI(freezeValue): object not exist", si.id, si.node) << endl;
}
catch( const CORBA::COMM_FAILURE& ) {}
catch( const CORBA::SystemException& ex ) {}
catch(...) {}
rcache.erase(si.id, si.node);
uwarn << set_err("UI(freezeValue): Timeout", si.id, si.node) << endl;
}
// ------------------------------------------------------------------------------------------------------------
/*!
* \param id - идентификатор датчика
* \param value - значение, которое необходимо установить
......
......@@ -44,6 +44,7 @@ IOController::IOController(const string& name, const string& section):
isPingDBServer(true)
{
auto conf = uniset_conf();
if( conf )
dbserverID = conf->getDBServer();
}
......@@ -54,6 +55,7 @@ IOController::IOController(ObjectId id):
isPingDBServer(true)
{
auto conf = uniset_conf();
if( conf )
dbserverID = conf->getDBServer();
}
......@@ -104,7 +106,7 @@ IOController::InitSignal IOController::signal_init()
// ------------------------------------------------------------------------------------------
void IOController::activateInit()
{
for( auto && io : ioList )
for( auto&& io : ioList )
{
try
{
......@@ -207,6 +209,7 @@ void IOController::localSetUndefinedState( IOStateList::iterator& li,
uniset_rwmutex_wrlock lock(usi->val_lock);
changed = (usi->undefined != undefined);
usi->undefined = undefined;
if( usi->undef_value != not_specified_value )
{
if( undefined )
......@@ -262,6 +265,68 @@ void IOController::localSetUndefinedState( IOStateList::iterator& li,
catch(...) {}
}
// ------------------------------------------------------------------------------------------
void IOController::freezeValue( uniset::ObjectId sid,
CORBA::Boolean set,
CORBA::Long value,
uniset::ObjectId sup_id )
{
auto li = ioList.end();
localFreezeValueIt( li, sid, set, value, sup_id );
}
// ------------------------------------------------------------------------------------------
void IOController::localFreezeValueIt( IOController::IOStateList::iterator& li,
uniset::ObjectId sid,
CORBA::Boolean set,
CORBA::Long value,
uniset::ObjectId sup_id )
{
if( sup_id == uniset::DefaultObjectId )
sup_id = getId();
// сохранение текущего состояния
if( li == ioList.end() )
{
if( sid != DefaultObjectId )
li = ioList.find(sid);
}
if( li == ioList.end() )
{
ostringstream err;
err << myname << "(localFreezeValue): Unknown sensor (" << sid << ")"
<< "name: " << uniset_conf()->oind->getNameById(sid);
throw IOController_i::NameNotFound(err.str().c_str());
}
localFreezeValue(li->second, set, value, sup_id);
}
// ------------------------------------------------------------------------------------------
void IOController::localFreezeValue( std::shared_ptr<USensorInfo>& usi,
CORBA::Boolean set,
CORBA::Long value,
uniset::ObjectId sup_id )
{
ulog4 << myname << "(localFreezeValue): (" << usi->si.id << ")"
<< uniset_conf()->oind->getNameById(usi->si.id)
<< " value=" << value
<< " set=" << set
<< " supplier=" << sup_id
<< endl;
{
// выставляем флаг заморозки
uniset_rwmutex_wrlock lock(usi->val_lock);
usi->frozen = set;
usi->frozen_value = value;
// берём текущее значение, чтобы его не затереть
// при вызове setValue()
value = usi->real_value;
}
localSetValue(usi, value, sup_id);
}
// ------------------------------------------------------------------------------------------
void IOController::setValue( uniset::ObjectId sid, CORBA::Long value, uniset::ObjectId sup_id )
{
auto li = ioList.end();
......@@ -300,6 +365,7 @@ long IOController::localSetValue( std::shared_ptr<USensorInfo>& usi,
bool changed = false;
bool blockChanged = false;
bool freezeChanged = false;
long retValue = value;
{
......@@ -311,25 +377,30 @@ long IOController::localSetValue( std::shared_ptr<USensorInfo>& usi,
bool blocked = ( usi->blocked || usi->undefined );
changed = ( usi->real_value != value );
// Смотрим поменялось ли состояние блокировки.
// т.е. смотрим записано ли у нас уже value = d_off_value и флаг блокировки
// т.к. если blocked=true то должно быть usi->value = usi->d_off_value
// если флаг снимется, то значит должны "восстанавливать" значение из real_value
blockChanged = ( blocked != (usi->value == usi->d_off_value ) );
// Выставление запоненного значения (real_value)
// если снялась блокировка или заморозка
blockChanged = ( blocked != (usi->value == usi->d_off_value) );
freezeChanged = ( usi->frozen != (usi->value == usi->frozen_value) );
if( changed || blockChanged )
if( changed || blockChanged || freezeChanged )
{
ulog4 << myname << "(localSetValue): (" << usi->si.id << ")"
<< uniset_conf()->oind->getNameById(usi->si.id)
<< " newvalue=" << value
<< " value=" << usi->value
<< " blocked=" << usi->blocked
<< " frozen=" << usi->frozen
<< " real_value=" << usi->real_value
<< " supplier=" << sup_id
<< endl;
usi->real_value = value;
if( usi->frozen )
usi->value = usi->frozen_value;
else
usi->value = (blocked ? usi->d_off_value : value);
retValue = usi->value;
usi->nchanges++; // статистика
......@@ -350,7 +421,7 @@ long IOController::localSetValue( std::shared_ptr<USensorInfo>& usi,
try
{
if( changed || blockChanged )
if( changed || blockChanged || freezeChanged )
{
uniset_rwmutex_wrlock l(usi->changeMutex);
usi->sigChange.emit(usi, this);
......@@ -360,7 +431,7 @@ long IOController::localSetValue( std::shared_ptr<USensorInfo>& usi,
try
{
if( changed || blockChanged )
if( changed || blockChanged || freezeChanged )
{
std::lock_guard<std::mutex> l(siganyMutex);
sigAnyChange.emit(usi, this);
......@@ -462,7 +533,7 @@ void IOController::dumpToDB()
{
// lock
// uniset_mutex_lock lock(ioMutex, 100);
for( auto && usi : ioList )
for( auto&& usi : ioList )
{
auto& s = usi.second;
......@@ -615,6 +686,7 @@ IOController::USensorInfo::USensorInfo(): d_value(1), d_off_value(0)
dbignore = false;
undefined = false;
blocked = false;
frozen = false;
supplier = uniset::DefaultObjectId;
// стоит ли выставлять текущее время
......@@ -684,7 +756,7 @@ void IOController::for_iolist( IOController::UFunction f )
{
uniset_rwmutex_rlock lck(ioMutex);
for( auto && s : ioList )
for( auto&& s : ioList )
f(s.second);
}
// ----------------------------------------------------------------------------------------
......
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