You need to sign in or sign up before continuing.
Commit 42a075e8 authored by Pavel Vainerman's avatar Pavel Vainerman

(MBExchange): SafeMode: step 2

parent bef27bf8
...@@ -893,7 +893,7 @@ namespace uniset ...@@ -893,7 +893,7 @@ namespace uniset
try try
{ {
if( it.subdev == IOBase::DefaultSubdev || it.safeval == IOBase::UnusedSafeValue ) if( it.subdev == IOBase::DefaultSubdev || !it.safevalDefined )
continue; continue;
if( it.stype == UniversalIO::DO || it.lamp ) if( it.stype == UniversalIO::DO || it.lamp )
...@@ -1080,7 +1080,7 @@ namespace uniset ...@@ -1080,7 +1080,7 @@ namespace uniset
try try
{ {
if( it.subdev == IOBase::DefaultSubdev || it.safeval == IOBase::UnusedSafeValue ) if( it.subdev == IOBase::DefaultSubdev || !it.safevalDefined )
continue; continue;
if( it.stype == UniversalIO::DO || it.lamp ) if( it.stype == UniversalIO::DO || it.lamp )
......
...@@ -221,37 +221,6 @@ namespace uniset ...@@ -221,37 +221,6 @@ namespace uniset
} }
} }
if( findArgParam("--" + prefix + "-safemode-reset-if-not-repond", conf->getArgc(), conf->getArgv()) != -1 )
{
safeMode = safeResetIfNotRespond;
vmonit(safeMode);
}
string safemode = conf->getArgParam("--" + prefix + "-safemode-external-control-sid", it.getProp("safeModeExternalControl"));
if( !safemode.empty() )
{
sidSafeModeExternal = conf->getSensorID(emode);
if( sidSafeModeExternal == DefaultObjectId )
{
ostringstream err;
err << myname << ": ID not found for " << safemode;
mbcrit << myname << "(init): " << err.str() << endl;
throw SystemError(err.str());
}
// если указан датчик, то
safeMode = safeExternalControl;
vmonit(safeMode);
}
string safemodeValue = conf->getArgParam("--" + prefix + "-safemode-external-control-value", it.getProp("safeModeExternalControlValue"));
if( !safemodeValue.empty() )
valueSafeModeExternal = uni_atoi(safemodeValue);
vmonit(valueSafeModeExternal);
activateTimeout = conf->getArgPInt("--" + prefix + "-activate-timeout", 20000); activateTimeout = conf->getArgPInt("--" + prefix + "-activate-timeout", 20000);
vmonit(allInitOK); vmonit(allInitOK);
...@@ -312,11 +281,6 @@ namespace uniset ...@@ -312,11 +281,6 @@ namespace uniset
cout << "--prefix-default-mbinit-ok 0,1 - Флаг инициализации. 1 - не ждать первого обмена с устройством, а сохранить при старте в SM значение 'default'" << endl; cout << "--prefix-default-mbinit-ok 0,1 - Флаг инициализации. 1 - не ждать первого обмена с устройством, а сохранить при старте в SM значение 'default'" << endl;
cout << "--prefix-query-max-count max - Максимальное количество запрашиваемых за один раз регистров (При условии no-query-optimization=0). По умолчанию: " << ModbusRTU::MAXDATALEN << "." << endl; cout << "--prefix-query-max-count max - Максимальное количество запрашиваемых за один раз регистров (При условии no-query-optimization=0). По умолчанию: " << ModbusRTU::MAXDATALEN << "." << endl;
cout << endl; cout << endl;
cout << "SafeMode:";
cout << "--prefix-safemode-reset-if-not-respond - Включить режим сброса значений в safeval, при пропадании связи с устройством" << endl;
cout << "--prefix-safemode-external-control-sid id - Управление сбросом значений в безопасное состояние по внешнему датчику." << endl;
cout << "--prefix-safemode-external-control-value val - Значение срабатывания для датчика управления сбросом. Default: 1" << endl;
cout << endl;
cout << " Logs: " << endl; cout << " Logs: " << endl;
cout << "--prefix-log-... - log control" << endl; cout << "--prefix-log-... - log control" << endl;
cout << " add-levels ... " << endl; cout << " add-levels ... " << endl;
...@@ -358,7 +322,7 @@ namespace uniset ...@@ -358,7 +322,7 @@ namespace uniset
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBExchange::step() void MBExchange::step()
{ {
if( !checkProcActive() ) if( !isProcActive() )
return; return;
if( ptInitChannel.checkTime() ) if( ptInitChannel.checkTime() )
...@@ -379,7 +343,7 @@ namespace uniset ...@@ -379,7 +343,7 @@ namespace uniset
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
bool MBExchange::checkProcActive() const bool MBExchange::isProcActive() const
{ {
return activated; return activated;
} }
...@@ -525,7 +489,7 @@ namespace uniset ...@@ -525,7 +489,7 @@ namespace uniset
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
bool MBExchange::checkUpdateSM( bool wrFunc, long mdev ) bool MBExchange::isUpdateSM( bool wrFunc, long mdev ) const noexcept
{ {
if( exchangeMode == emSkipExchange || mdev == emSkipExchange ) if( exchangeMode == emSkipExchange || mdev == emSkipExchange )
{ {
...@@ -561,7 +525,7 @@ namespace uniset ...@@ -561,7 +525,7 @@ namespace uniset
return true; return true;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
bool MBExchange::checkPoll( bool wrFunc ) const bool MBExchange::isPollEnabled( bool wrFunc ) const noexcept
{ {
if( exchangeMode == emWriteOnly && !wrFunc ) if( exchangeMode == emWriteOnly && !wrFunc )
{ {
...@@ -584,6 +548,14 @@ namespace uniset ...@@ -584,6 +548,14 @@ namespace uniset
return true; return true;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
bool MBExchange::isSafeMode( std::shared_ptr<MBExchange::RTUDevice>& dev ) const noexcept
{
if( !dev )
return false;
return ( dev->safeMode != safeNone );
}
// -----------------------------------------------------------------------------
void MBExchange::printMap( MBExchange::RTUDeviceMap& m ) void MBExchange::printMap( MBExchange::RTUDeviceMap& m )
{ {
cout << "devices: " << endl; cout << "devices: " << endl;
...@@ -610,6 +582,7 @@ namespace uniset ...@@ -610,6 +582,7 @@ namespace uniset
<< " respond_timeout=" << d.resp_Delay.getOffDelay() << " respond_timeout=" << d.resp_Delay.getOffDelay()
<< " respond_state=" << d.resp_state << " respond_state=" << d.resp_state
<< " respond_invert=" << d.resp_invert << " respond_invert=" << d.resp_invert
<< " safeMode=" << (MBExchange::SafeMode)d.safeMode
<< endl; << endl;
...@@ -1028,7 +1001,7 @@ namespace uniset ...@@ -1028,7 +1001,7 @@ namespace uniset
} }
} }
if( !checkPoll(ModbusRTU::isWriteFunction(p->mbfunc)) ) if( !isPollEnabled(ModbusRTU::isWriteFunction(p->mbfunc)) )
return true; return true;
if( p->q_count == 0 ) if( p->q_count == 0 )
...@@ -1234,7 +1207,7 @@ namespace uniset ...@@ -1234,7 +1207,7 @@ namespace uniset
{ {
mblog3 << myname << "(updateSM):(IOBadParam) " << ex.err << endl; mblog3 << myname << "(updateSM):(IOBadParam) " << ex.err << endl;
} }
catch(IONotifyController_i::BadRange ) catch( IONotifyController_i::BadRange )
{ {
mblog3 << myname << "(updateSM): (BadRange)..." << endl; mblog3 << myname << "(updateSM): (BadRange)..." << endl;
} }
...@@ -1247,12 +1220,50 @@ namespace uniset ...@@ -1247,12 +1220,50 @@ namespace uniset
mblog3 << myname << "(updateSM): CORBA::SystemException: " mblog3 << myname << "(updateSM): CORBA::SystemException: "
<< ex.NP_minorString() << endl; << ex.NP_minorString() << endl;
} }
catch(...) catch( std::exception& ex )
{ {
mblog3 << myname << "(updateSM): check modeSensor..catch ..." << endl; mblog3 << myname << "(updateSM): check modeSensor: " << ex.what() << endl;
} }
}
if( d->safemode_id != DefaultObjectId )
{
try
{
if( !shm->isLocalwork() )
{
if( shm->localGetValue(d->safemode_it, d->safemode_id) == d->safemode_value )
d->safeMode = safeExternalControl;
else
d->safeMode = safeNone;
}
}
catch(IOController_i::NameNotFound& ex)
{
mblog3 << myname << "(updateSM):(NameNotFound) " << ex.err << endl;
}
catch(IOController_i::IOBadParam& ex )
{
mblog3 << myname << "(updateSM):(IOBadParam) " << ex.err << endl;
}
catch( IONotifyController_i::BadRange )
{
mblog3 << myname << "(updateSM): (BadRange)..." << endl;
}
catch( const uniset::Exception& ex )
{
mblog3 << myname << "(updateSM): " << ex << endl;
}
catch( const CORBA::SystemException& ex )
{
mblog3 << myname << "(updateSM): CORBA::SystemException: "
<< ex.NP_minorString() << endl;
}
catch( std::exception& ex )
{
mblog3 << myname << "(updateSM): check safemodeSensor: " << ex.what() << endl;
}
}
}
for( auto && m : d->pollmap ) for( auto && m : d->pollmap )
{ {
...@@ -1300,6 +1311,7 @@ namespace uniset ...@@ -1300,6 +1311,7 @@ namespace uniset
mblog3 << myname << "(updateSM): catch ..." << endl; mblog3 << myname << "(updateSM): catch ..." << endl;
} }
// эта проверка
if( it == regmap->end() ) if( it == regmap->end() )
break; break;
} }
...@@ -1327,22 +1339,26 @@ namespace uniset ...@@ -1327,22 +1339,26 @@ namespace uniset
if( !save && write_only ) if( !save && write_only )
return; return;
if( !checkUpdateSM(save, r->dev->mode) ) if( !isUpdateSM(save, r->dev->mode) )
return; return;
// если ещё не обменивались ни разу с устройством, то ингнорируем (не обновляем значение в SM) // если ещё не обменивались ни разу с устройством, то ингнорируем (не обновляем значение в SM)
if( !r->mb_initOK ) if( !r->mb_initOK && !isSafeMode(r->dev) )
return; return;
bool useSafeval = isSafeMode(r->dev) && p->safevalDefined;
mblog3 << myname << "(updateP): sid=" << p->si.id mblog3 << myname << "(updateP): sid=" << p->si.id
<< " mbval=" << r->mbval << " mbval=" << r->mbval
<< " vtype=" << p->vType << " vtype=" << p->vType
<< " rnum=" << p->rnum << " rnum=" << p->rnum
<< " nbit=" << p->nbit << " nbit=" << (int)p->nbit
<< " save=" << save << " save=" << save
<< " ioype=" << p->stype << " ioype=" << p->stype
<< " mb_initOK=" << r->mb_initOK << " mb_initOK=" << r->mb_initOK
<< " sm_initOK=" << r->sm_initOK << " sm_initOK=" << r->sm_initOK
<< " safeMode=" << isSafeMode(r->dev)
<< " safevalDefined=" << p->safevalDefined
<< endl; << endl;
try try
...@@ -1357,7 +1373,7 @@ namespace uniset ...@@ -1357,7 +1373,7 @@ namespace uniset
{ {
if( r->mb_initOK ) if( r->mb_initOK )
{ {
bool set = IOBase::processingAsDO( p, shm, force_out ); bool set = useSafeval ? p->safeval : IOBase::processingAsDO( p, shm, force_out );
b.set(p->nbit, set); b.set(p->nbit, set);
r->mbval = b.mdata(); r->mbval = b.mdata();
r->sm_initOK = true; r->sm_initOK = true;
...@@ -1365,7 +1381,7 @@ namespace uniset ...@@ -1365,7 +1381,7 @@ namespace uniset
} }
else else
{ {
bool set = b[p->nbit]; bool set = useSafeval ? (bool)p->safeval : b[p->nbit];
IOBase::processingAsDI( p, set, shm, force ); IOBase::processingAsDI( p, set, shm, force );
} }
...@@ -1378,14 +1394,15 @@ namespace uniset ...@@ -1378,14 +1394,15 @@ namespace uniset
{ {
if( r->mb_initOK ) if( r->mb_initOK )
{ {
if( p->stype == UniversalIO::DI || if( useSafeval )
p->stype == UniversalIO::DO ) r->mbval = p->safeval;
else
{ {
r->mbval = IOBase::processingAsDO( p, shm, force_out ); if( p->stype == UniversalIO::DI || p->stype == UniversalIO::DO )
r->mbval = IOBase::processingAsDO( p, shm, force_out );
else
r->mbval = IOBase::processingAsAO( p, shm, force_out );
} }
else
r->mbval = IOBase::processingAsAO( p, shm, force_out );
r->sm_initOK = true; r->sm_initOK = true;
} }
} }
...@@ -1394,10 +1411,18 @@ namespace uniset ...@@ -1394,10 +1411,18 @@ namespace uniset
if( p->stype == UniversalIO::DI || if( p->stype == UniversalIO::DI ||
p->stype == UniversalIO::DO ) p->stype == UniversalIO::DO )
{ {
IOBase::processingAsDI( p, r->mbval, shm, force ); if( useSafeval )
IOBase::processingAsDI( p, p->safeval, shm, force );
else
IOBase::processingAsDI( p, r->mbval, shm, force );
} }
else else
IOBase::processingAsAI( p, (signed short)(r->mbval), shm, force ); {
if( useSafeval )
IOBase::processingAsAI( p, p->safeval, shm, force );
else
IOBase::processingAsAI( p, (signed short)(r->mbval), shm, force );
}
} }
return; return;
...@@ -1413,27 +1438,34 @@ namespace uniset ...@@ -1413,27 +1438,34 @@ namespace uniset
{ {
if( r->mb_initOK ) if( r->mb_initOK )
{ {
if( p->stype == UniversalIO::DI || if( useSafeval )
p->stype == UniversalIO::DO ) r->mbval = p->safeval;
else
{ {
r->mbval = (signed short)IOBase::processingAsDO( p, shm, force_out ); if( p->stype == UniversalIO::DI || p->stype == UniversalIO::DO )
r->mbval = (int16_t)IOBase::processingAsDO( p, shm, force_out );
else
r->mbval = (int16_t)IOBase::processingAsAO( p, shm, force_out );
} }
else
r->mbval = (signed short)IOBase::processingAsAO( p, shm, force_out );
r->sm_initOK = true; r->sm_initOK = true;
} }
} }
else else
{ {
if( p->stype == UniversalIO::DI || if( p->stype == UniversalIO::DI || p->stype == UniversalIO::DO )
p->stype == UniversalIO::DO )
{ {
IOBase::processingAsDI( p, r->mbval, shm, force ); if( useSafeval )
IOBase::processingAsDI( p, p->safeval, shm, force );
else
IOBase::processingAsDI( p, r->mbval, shm, force );
} }
else else
{ {
IOBase::processingAsAI( p, (signed short)(r->mbval), shm, force ); if( useSafeval )
IOBase::processingAsAI( p, p->safeval, shm, force );
else
IOBase::processingAsAI( p, (signed short)(r->mbval), shm, force );
} }
} }
...@@ -1445,28 +1477,25 @@ namespace uniset ...@@ -1445,28 +1477,25 @@ namespace uniset
{ {
if( r->mb_initOK ) if( r->mb_initOK )
{ {
if( p->stype == UniversalIO::DI || if( useSafeval )
p->stype == UniversalIO::DO ) r->mbval = p->safeval;
else
{ {
r->mbval = (uint16_t)IOBase::processingAsDO( p, shm, force_out ); if( p->stype == UniversalIO::DI || p->stype == UniversalIO::DO )
r->mbval = (uint16_t)IOBase::processingAsDO( p, shm, force_out );
else
r->mbval = (uint16_t)IOBase::processingAsAO( p, shm, force_out );
} }
else
r->mbval = (uint16_t)IOBase::processingAsAO( p, shm, force_out );
r->sm_initOK = true; r->sm_initOK = true;
} }
} }
else else
{ {
if( p->stype == UniversalIO::DI || if( p->stype == UniversalIO::DI || p->stype == UniversalIO::DO )
p->stype == UniversalIO::DO ) IOBase::processingAsDI( p, useSafeval ? p->safeval : r->mbval, shm, force );
{
IOBase::processingAsDI( p, r->mbval, shm, force );
}
else else
{ IOBase::processingAsAI( p, useSafeval ? p->safeval : (uint16_t)r->mbval, shm, force );
IOBase::processingAsAI( p, (uint16_t)r->mbval, shm, force );
}
} }
return; return;
...@@ -1484,7 +1513,7 @@ namespace uniset ...@@ -1484,7 +1513,7 @@ namespace uniset
{ {
if( r->mb_initOK ) if( r->mb_initOK )
{ {
long v = IOBase::processingAsAO( p, shm, force_out ); long v = useSafeval ? p->safeval : IOBase::processingAsAO( p, shm, force_out );
VTypes::Byte b(r->mbval); VTypes::Byte b(r->mbval);
b.raw.b[p->nbyte - 1] = v; b.raw.b[p->nbyte - 1] = v;
r->mbval = b.raw.w; r->mbval = b.raw.w;
...@@ -1493,8 +1522,13 @@ namespace uniset ...@@ -1493,8 +1522,13 @@ namespace uniset
} }
else else
{ {
VTypes::Byte b(r->mbval); if( useSafeval )
IOBase::processingAsAI( p, b.raw.b[p->nbyte - 1], shm, force ); IOBase::processingAsAI( p, p->safeval, shm, force );
else
{
VTypes::Byte b(r->mbval);
IOBase::processingAsAI( p, b.raw.b[p->nbyte - 1], shm, force );
}
} }
return; return;
...@@ -1507,7 +1541,8 @@ namespace uniset ...@@ -1507,7 +1541,8 @@ namespace uniset
{ {
if( r->mb_initOK ) if( r->mb_initOK )
{ {
float f = IOBase::processingFasAO( p, shm, force_out ); //! \warning НЕ РЕШЕНО safeval --> float !
float f = useSafeval ? (float)p->safeval : IOBase::processingFasAO( p, shm, force_out );
if( p->vType == VTypes::vtF2 ) if( p->vType == VTypes::vtF2 )
{ {
...@@ -1529,25 +1564,32 @@ namespace uniset ...@@ -1529,25 +1564,32 @@ namespace uniset
} }
else else
{ {
DataGuard d(VTypes::F2::wsize()); if( useSafeval )
for( size_t k = 0; k < VTypes::F2::wsize(); k++, i++ )
d.data[k] = i->second->mbval;
float f = 0;
if( p->vType == VTypes::vtF2 )
{ {
VTypes::F2 f1(d.data, VTypes::F2::wsize()); IOBase::processingAsAI( p, p->safeval, shm, force );
f = (float)f1;
} }
else if( p->vType == VTypes::vtF2r ) else
{ {
VTypes::F2r f1(d.data, VTypes::F2r::wsize()); DataGuard d(VTypes::F2::wsize());
f = (float)f1;
} for( size_t k = 0; k < VTypes::F2::wsize(); k++, i++ )
d.data[k] = i->second->mbval;
float f = 0;
IOBase::processingFasAI( p, f, shm, force ); if( p->vType == VTypes::vtF2 )
{
VTypes::F2 f1(d.data, VTypes::F2::wsize());
f = (float)f1;
}
else if( p->vType == VTypes::vtF2r )
{
VTypes::F2r f1(d.data, VTypes::F2r::wsize());
f = (float)f1;
}
IOBase::processingFasAI( p, f, shm, force );
}
} }
} }
else if( p->vType == VTypes::vtF4 ) else if( p->vType == VTypes::vtF4 )
...@@ -1558,7 +1600,8 @@ namespace uniset ...@@ -1558,7 +1600,8 @@ namespace uniset
{ {
if( r->mb_initOK ) if( r->mb_initOK )
{ {
float f = IOBase::processingFasAO( p, shm, force_out ); //! \warning НЕ РЕШЕНО safeval --> float !
float f = useSafeval ? (float)p->safeval : IOBase::processingFasAO( p, shm, force_out );
VTypes::F4 f4(f); VTypes::F4 f4(f);
for( size_t k = 0; k < VTypes::F4::wsize(); k++, i++ ) for( size_t k = 0; k < VTypes::F4::wsize(); k++, i++ )
...@@ -1569,14 +1612,21 @@ namespace uniset ...@@ -1569,14 +1612,21 @@ namespace uniset
} }
else else
{ {
DataGuard d(VTypes::F4::wsize()); if( useSafeval )
{
IOBase::processingAsAI( p, p->safeval, shm, force );
}
else
{
DataGuard d(VTypes::F4::wsize());
for( size_t k = 0; k < VTypes::F4::wsize(); k++, i++ ) for( size_t k = 0; k < VTypes::F4::wsize(); k++, i++ )
d.data[k] = i->second->mbval; d.data[k] = i->second->mbval;
VTypes::F4 f(d.data, VTypes::F4::wsize()); VTypes::F4 f(d.data, VTypes::F4::wsize());
IOBase::processingFasAI( p, (float)f, shm, force ); IOBase::processingFasAI( p, (float)f, shm, force );
}
} }
} }
else if( p->vType == VTypes::vtI2 || p->vType == VTypes::vtI2r ) else if( p->vType == VTypes::vtI2 || p->vType == VTypes::vtI2r )
...@@ -1587,7 +1637,7 @@ namespace uniset ...@@ -1587,7 +1637,7 @@ namespace uniset
{ {
if( r->mb_initOK ) if( r->mb_initOK )
{ {
long v = IOBase::processingAsAO( p, shm, force_out ); long v = useSafeval ? p->safeval : IOBase::processingAsAO( p, shm, force_out );
if( p->vType == VTypes::vtI2 ) if( p->vType == VTypes::vtI2 )
{ {
...@@ -1609,25 +1659,32 @@ namespace uniset ...@@ -1609,25 +1659,32 @@ namespace uniset
} }
else else
{ {
DataGuard d(VTypes::I2::wsize()); if( useSafeval )
for( size_t k = 0; k < VTypes::I2::wsize(); k++, i++ )
d.data[k] = i->second->mbval;
int v = 0;
if( p->vType == VTypes::vtI2 )
{ {
VTypes::I2 i2(d.data, VTypes::I2::wsize()); IOBase::processingAsAI( p, p->safeval, shm, force );
v = (int)i2;
} }
else if( p->vType == VTypes::vtI2r ) else
{ {
VTypes::I2r i2(d.data, VTypes::I2::wsize()); DataGuard d(VTypes::I2::wsize());
v = (int)i2;
} for( size_t k = 0; k < VTypes::I2::wsize(); k++, i++ )
d.data[k] = i->second->mbval;
int v = 0;
if( p->vType == VTypes::vtI2 )
{
VTypes::I2 i2(d.data, VTypes::I2::wsize());
v = (int)i2;
}
else if( p->vType == VTypes::vtI2r )
{
VTypes::I2r i2(d.data, VTypes::I2::wsize());
v = (int)i2;
}
IOBase::processingAsAI( p, v, shm, force ); IOBase::processingAsAI( p, v, shm, force );
}
} }
} }
else if( p->vType == VTypes::vtU2 || p->vType == VTypes::vtU2r ) else if( p->vType == VTypes::vtU2 || p->vType == VTypes::vtU2r )
...@@ -1638,7 +1695,7 @@ namespace uniset ...@@ -1638,7 +1695,7 @@ namespace uniset
{ {
if( r->mb_initOK ) if( r->mb_initOK )
{ {
long v = IOBase::processingAsAO( p, shm, force_out ); long v = useSafeval ? p->safeval : IOBase::processingAsAO( p, shm, force_out );
if( p->vType == VTypes::vtU2 ) if( p->vType == VTypes::vtU2 )
{ {
...@@ -1660,25 +1717,33 @@ namespace uniset ...@@ -1660,25 +1717,33 @@ namespace uniset
} }
else else
{ {
DataGuard d(VTypes::U2::wsize()); if( useSafeval )
for( size_t k = 0; k < VTypes::U2::wsize(); k++, i++ )
d.data[k] = i->second->mbval;
uint32_t v = 0;
if( p->vType == VTypes::vtU2 )
{ {
VTypes::U2 u2(d.data, VTypes::U2::wsize()); IOBase::processingAsAI( p, p->safeval, shm, force );
v = (uint32_t)u2;
} }
else if( p->vType == VTypes::vtU2r ) else
{ {
VTypes::U2r u2(d.data, VTypes::U2::wsize());
v = (uint32_t)u2;
}
IOBase::processingAsAI( p, v, shm, force ); DataGuard d(VTypes::U2::wsize());
for( size_t k = 0; k < VTypes::U2::wsize(); k++, i++ )
d.data[k] = i->second->mbval;
uint32_t v = 0;
if( p->vType == VTypes::vtU2 )
{
VTypes::U2 u2(d.data, VTypes::U2::wsize());
v = (uint32_t)u2;
}
else if( p->vType == VTypes::vtU2r )
{
VTypes::U2r u2(d.data, VTypes::U2::wsize());
v = (uint32_t)u2;
}
IOBase::processingAsAI( p, v, shm, force );
}
} }
} }
...@@ -1725,53 +1790,77 @@ namespace uniset ...@@ -1725,53 +1790,77 @@ namespace uniset
using namespace ModbusRTU; using namespace ModbusRTU;
bool save = isWriteFunction( r->mbfunc ); bool save = isWriteFunction( r->mbfunc );
if( !checkUpdateSM(save, r->dev->mode) ) if( !isUpdateSM(save, r->dev->mode) )
return; return;
for( auto it = r->slst.begin(); it != r->slst.end(); ++it )
{ {
for( auto it = r->slst.begin(); it != r->slst.end(); ++it ) try
{ {
try bool safeMode = isSafeMode(r->dev) && it->safevalDefined;
if( r->mtrType == MTR::mtT1 )
{ {
if( r->mtrType == MTR::mtT1 ) if( save )
r->mbval = safeMode ? it->safeval : IOBase::processingAsAO( &(*it), shm, force_out );
else
{ {
if( save ) if( safeMode )
r->mbval = IOBase::processingAsAO( &(*it), shm, force_out ); {
IOBase::processingAsAI( &(*it), it->safeval, shm, force );
}
else else
{ {
MTR::T1 t(r->mbval); MTR::T1 t(r->mbval);
IOBase::processingAsAI( &(*it), t.val, shm, force ); IOBase::processingAsAI( &(*it), t.val, shm, force );
} }
continue;
} }
if( r->mtrType == MTR::mtT2 ) continue;
}
if( r->mtrType == MTR::mtT2 )
{
if( save )
{ {
if( save ) long val = safeMode ? it->safeval : IOBase::processingAsAO( &(*it), shm, force_out );
MTR::T2 t(val);
r->mbval = t.val;
}
else
{
if( safeMode )
{ {
MTR::T2 t(IOBase::processingAsAO( &(*it), shm, force_out )); IOBase::processingAsAI( &(*it), it->safeval, shm, force );
r->mbval = t.val;
} }
else else
{ {
MTR::T2 t(r->mbval); MTR::T2 t(r->mbval);
IOBase::processingAsAI( &(*it), t.val, shm, force ); IOBase::processingAsAI( &(*it), t.val, shm, force );
} }
continue;
} }
if( r->mtrType == MTR::mtT3 ) continue;
}
if( r->mtrType == MTR::mtT3 )
{
auto i = rit;
if( save )
{ {
auto i = rit; long val = safeMode ? it->safeval : IOBase::processingAsAO( &(*it), shm, force_out );
if( save ) MTR::T3 t(val);
{
MTR::T3 t(IOBase::processingAsAO( &(*it), shm, force_out ));
for( size_t k = 0; k < MTR::T3::wsize(); k++, i++ ) for( size_t k = 0; k < MTR::T3::wsize(); k++, i++ )
i->second->mbval = t.raw.v[k]; i->second->mbval = t.raw.v[k];
}
else
{
if( safeMode )
{
IOBase::processingAsAI( &(*it), it->safeval, shm, force );
} }
else else
{ {
...@@ -1783,35 +1872,50 @@ namespace uniset ...@@ -1783,35 +1872,50 @@ namespace uniset
MTR::T3 t(d.data, MTR::T3::wsize()); MTR::T3 t(d.data, MTR::T3::wsize());
IOBase::processingAsAI( &(*it), (long)t, shm, force ); IOBase::processingAsAI( &(*it), (long)t, shm, force );
} }
continue;
} }
if( r->mtrType == MTR::mtT4 ) continue;
}
if( r->mtrType == MTR::mtT4 )
{
if( save )
{
mbwarn << myname << "(updateMTR): write (T4) reg(" << dat2str(r->mbreg) << ") to MTR NOT YET!!!" << endl;
}
else
{ {
if( save ) if( safeMode )
{ {
mbwarn << myname << "(updateMTR): write (T4) reg(" << dat2str(r->mbreg) << ") to MTR NOT YET!!!" << endl; IOBase::processingAsAI( &(*it), it->safeval, shm, force );
} }
else else
{ {
MTR::T4 t(r->mbval); MTR::T4 t(r->mbval);
IOBase::processingAsAI( &(*it), uni_atoi(t.sval), shm, force ); IOBase::processingAsAI( &(*it), uni_atoi(t.sval), shm, force );
} }
continue;
} }
if( r->mtrType == MTR::mtT5 ) continue;
}
if( r->mtrType == MTR::mtT5 )
{
auto i = rit;
if( save )
{ {
auto i = rit; long val = safeMode ? it->safeval : IOBase::processingAsAO( &(*it), shm, force_out );
if( save ) MTR::T5 t(val);
for( size_t k = 0; k < MTR::T5::wsize(); k++, i++ )
i->second->mbval = t.raw.v[k];
}
else
{
if( safeMode )
{ {
MTR::T5 t(IOBase::processingAsAO( &(*it), shm, force_out )); IOBase::processingAsAI( &(*it), it->safeval, shm, force );
for( size_t k = 0; k < MTR::T5::wsize(); k++, i++ )
i->second->mbval = t.raw.v[k];
} }
else else
{ {
...@@ -1824,20 +1928,29 @@ namespace uniset ...@@ -1824,20 +1928,29 @@ namespace uniset
IOBase::processingFasAI( &(*it), (float)t.val, shm, force ); IOBase::processingFasAI( &(*it), (float)t.val, shm, force );
} }
continue;
} }
if( r->mtrType == MTR::mtT6 ) continue;
}
if( r->mtrType == MTR::mtT6 )
{
auto i = rit;
if( save )
{ {
auto i = rit; long val = safeMode ? it->safeval : IOBase::processingAsAO( &(*it), shm, force_out );
if( save ) MTR::T6 t(val);
{
MTR::T6 t(IOBase::processingAsAO( &(*it), shm, force_out ));
for( size_t k = 0; k < MTR::T6::wsize(); k++, i++ ) for( size_t k = 0; k < MTR::T6::wsize(); k++, i++ )
i->second->mbval = t.raw.v[k]; i->second->mbval = t.raw.v[k];
}
else
{
if( safeMode )
{
IOBase::processingAsAI( &(*it), it->safeval, shm, force );
} }
else else
{ {
...@@ -1850,20 +1963,28 @@ namespace uniset ...@@ -1850,20 +1963,28 @@ namespace uniset
IOBase::processingFasAI( &(*it), (float)t.val, shm, force ); IOBase::processingFasAI( &(*it), (float)t.val, shm, force );
} }
continue;
} }
if( r->mtrType == MTR::mtT7 ) continue;
}
if( r->mtrType == MTR::mtT7 )
{
auto i = rit;
if( save )
{ {
auto i = rit; long val = safeMode ? it->safeval : IOBase::processingAsAO( &(*it), shm, force_out );
MTR::T7 t(val);
if( save ) for( size_t k = 0; k < MTR::T7::wsize(); k++, i++ )
i->second->mbval = t.raw.v[k];
}
else
{
if( safeMode )
{ {
MTR::T7 t(IOBase::processingAsAO( &(*it), shm, force_out )); IOBase::processingAsAI( &(*it), it->safeval, shm, force );
for( size_t k = 0; k < MTR::T7::wsize(); k++, i++ )
i->second->mbval = t.raw.v[k];
} }
else else
{ {
...@@ -1876,53 +1997,81 @@ namespace uniset ...@@ -1876,53 +1997,81 @@ namespace uniset
IOBase::processingFasAI( &(*it), (float)t.val, shm, force ); IOBase::processingFasAI( &(*it), (float)t.val, shm, force );
} }
continue;
} }
if( r->mtrType == MTR::mtT16 ) continue;
}
if( r->mtrType == MTR::mtT16 )
{
if( save )
{ {
if( save ) //! \warning НЕ РЕШЕНО safeval --> float !
float fval = safeMode ? (float)it->safeval : IOBase::processingFasAO( &(*it), shm, force_out );
MTR::T16 t(fval);
r->mbval = t.val;
}
else
{
if( safeMode )
{ {
MTR::T16 t(IOBase::processingFasAO( &(*it), shm, force_out )); IOBase::processingAsAI( &(*it), it->safeval, shm, force );
r->mbval = t.val;
} }
else else
{ {
MTR::T16 t(r->mbval); MTR::T16 t(r->mbval);
IOBase::processingFasAI( &(*it), t.fval, shm, force ); IOBase::processingFasAI( &(*it), t.fval, shm, force );
} }
continue;
} }
if( r->mtrType == MTR::mtT17 ) continue;
}
if( r->mtrType == MTR::mtT17 )
{
if( save )
{ {
if( save ) //! \warning НЕ РЕШЕНО safeval --> float !
float fval = safeMode ? (float)it->safeval : IOBase::processingFasAO( &(*it), shm, force_out );
MTR::T17 t(fval);
r->mbval = t.val;
}
else
{
if( safeMode )
{ {
MTR::T17 t(IOBase::processingFasAO( &(*it), shm, force_out )); IOBase::processingAsAI( &(*it), it->safeval, shm, force );
r->mbval = t.val;
} }
else else
{ {
MTR::T17 t(r->mbval); MTR::T17 t(r->mbval);
IOBase::processingFasAI( &(*it), t.fval, shm, force ); IOBase::processingFasAI( &(*it), t.fval, shm, force );
} }
continue;
} }
if( r->mtrType == MTR::mtF1 ) continue;
}
if( r->mtrType == MTR::mtF1 )
{
auto i = rit;
if( save )
{ {
auto i = rit; //! \warning НЕ РЕШЕНО safeval --> float !
float f = safeMode ? (float)it->safeval : IOBase::processingFasAO( &(*it), shm, force_out );
MTR::F1 f1(f);
if( save ) for( size_t k = 0; k < MTR::F1::wsize(); k++, i++ )
i->second->mbval = f1.raw.v[k];
}
else
{
if( safeMode )
{ {
float f = IOBase::processingFasAO( &(*it), shm, force_out ); IOBase::processingAsAI( &(*it), it->safeval, shm, force );
MTR::F1 f1(f);
for( size_t k = 0; k < MTR::F1::wsize(); k++, i++ )
i->second->mbval = f1.raw.v[k];
} }
else else
{ {
...@@ -1934,35 +2083,35 @@ namespace uniset ...@@ -1934,35 +2083,35 @@ namespace uniset
MTR::F1 t(d.data, MTR::F1::wsize()); MTR::F1 t(d.data, MTR::F1::wsize());
IOBase::processingFasAI( &(*it), (float)t, shm, force ); IOBase::processingFasAI( &(*it), (float)t, shm, force );
} }
continue;
} }
continue;
} }
catch(IOController_i::NameNotFound& ex) }
{ catch(IOController_i::NameNotFound& ex)
mblog3 << myname << "(updateMTR):(NameNotFound) " << ex.err << endl; {
} mblog3 << myname << "(updateMTR):(NameNotFound) " << ex.err << endl;
catch(IOController_i::IOBadParam& ex ) }
{ catch(IOController_i::IOBadParam& ex )
mblog3 << myname << "(updateMTR):(IOBadParam) " << ex.err << endl; {
} mblog3 << myname << "(updateMTR):(IOBadParam) " << ex.err << endl;
catch(IONotifyController_i::BadRange ) }
{ catch(IONotifyController_i::BadRange )
mblog3 << myname << "(updateMTR): (BadRange)..." << endl; {
} mblog3 << myname << "(updateMTR): (BadRange)..." << endl;
catch( const uniset::Exception& ex ) }
{ catch( const uniset::Exception& ex )
mblog3 << myname << "(updateMTR): " << ex << endl; {
} mblog3 << myname << "(updateMTR): " << ex << endl;
catch( const CORBA::SystemException& ex ) }
{ catch( const CORBA::SystemException& ex )
mblog3 << myname << "(updateMTR): CORBA::SystemException: " {
<< ex.NP_minorString() << endl; mblog3 << myname << "(updateMTR): CORBA::SystemException: "
} << ex.NP_minorString() << endl;
catch(...) }
{ catch(...)
mblog3 << myname << "(updateMTR): catch ..." << endl; {
} mblog3 << myname << "(updateMTR): catch ..." << endl;
} }
} }
} }
...@@ -1986,46 +2135,23 @@ namespace uniset ...@@ -1986,46 +2135,23 @@ namespace uniset
return; return;
} }
if( exchangeMode == emSkipExchange || r->dev->mode == emSkipExchange ) if( !isUpdateSM(save, r->dev->mode) )
{
mblog3 << myname << "(updateRTU188):"
<< " skip... mode=emSkipExchange " << endl;
return; return;
}
if( save && (exchangeMode == emReadOnly || r->dev->mode == emReadOnly) )
{
mblog3 << myname << "(updateRTU188):"
<< " skip... mode=emReadOnly " << endl;
return;
}
if( !save && ( exchangeMode == emWriteOnly || r->dev->mode == emWriteOnly) )
{
mblog3 << myname << "(updateRTU188):"
<< " skip... mode=emWriteOnly " << endl;
return;
}
if( save && ( exchangeMode == emSkipSaveToSM || r->dev->mode == emSkipSaveToSM) )
{
mblog3 << myname << "(updateRT188):"
<< " skip... mode=emSkipSaveToSM " << endl;
return;
}
for( auto it = r->slst.begin(); it != r->slst.end(); ++it ) for( auto it = r->slst.begin(); it != r->slst.end(); ++it )
{ {
try try
{ {
bool safeMode = isSafeMode(r->dev) && it->safevalDefined;
if( it->stype == UniversalIO::DI ) if( it->stype == UniversalIO::DI )
{ {
bool set = r->dev->rtu188->getState(r->rtuJack, r->rtuChan, it->stype); bool set = safeMode ? (bool)it->safeval : r->dev->rtu188->getState(r->rtuJack, r->rtuChan, it->stype);
IOBase::processingAsDI( &(*it), set, shm, force ); IOBase::processingAsDI( &(*it), set, shm, force );
} }
else if( it->stype == UniversalIO::AI ) else if( it->stype == UniversalIO::AI )
{ {
long val = r->dev->rtu188->getInt(r->rtuJack, r->rtuChan, it->stype); long val = safeMode ? it->safeval : r->dev->rtu188->getInt(r->rtuJack, r->rtuChan, it->stype);
IOBase::processingAsAI( &(*it), val, shm, force ); IOBase::processingAsAI( &(*it), val, shm, force );
} }
} }
...@@ -2179,7 +2305,7 @@ namespace uniset ...@@ -2179,7 +2305,7 @@ namespace uniset
if( p.nbit < 0 || p.nbit >= ModbusRTU::BitsPerData ) if( p.nbit < 0 || p.nbit >= ModbusRTU::BitsPerData )
{ {
mbcrit << myname << "(initRSProperty): BAD nbit=" << p.nbit mbcrit << myname << "(initRSProperty): BAD nbit=" << (int)p.nbit
<< ". (0 >= nbit < " << ModbusRTU::BitsPerData << ")." << endl; << ". (0 >= nbit < " << ModbusRTU::BitsPerData << ")." << endl;
return false; return false;
} }
...@@ -2417,7 +2543,7 @@ namespace uniset ...@@ -2417,7 +2543,7 @@ namespace uniset
{ {
if( fn == ModbusRTU::fnReadCoilStatus || fn == ModbusRTU::fnReadInputStatus ) if( fn == ModbusRTU::fnReadCoilStatus || fn == ModbusRTU::fnReadInputStatus )
{ {
mbcrit << myname << "(initItem): MISMATCHED CONFIGURATION! nbit=" << p.nbit << " func=" << fn mbcrit << myname << "(initItem): MISMATCHED CONFIGURATION! nbit=" << (int)p.nbit << " func=" << fn
<< " for " << it.getProp("name") << endl; << " for " << it.getProp("name") << endl;
return false; return false;
} }
...@@ -2709,7 +2835,7 @@ namespace uniset ...@@ -2709,7 +2835,7 @@ namespace uniset
os << " (" << ModbusRTU::dat2str(p.reg->mbreg) << ")" os << " (" << ModbusRTU::dat2str(p.reg->mbreg) << ")"
<< " sid=" << p.si.id << " sid=" << p.si.id
<< " stype=" << p.stype << " stype=" << p.stype
<< " nbit=" << p.nbit << " nbit=" << (int)p.nbit
<< " nbyte=" << p.nbyte << " nbyte=" << p.nbyte
<< " rnum=" << p.rnum << " rnum=" << p.rnum
<< " safeval=" << p.safeval << " safeval=" << p.safeval
...@@ -2762,18 +2888,20 @@ namespace uniset ...@@ -2762,18 +2888,20 @@ namespace uniset
return false; return false;
} }
d->second->ask_every_reg = it.getIntProp("ask_every_reg"); auto& dev = d->second;
dev->ask_every_reg = it.getIntProp("ask_every_reg");
mbinfo << myname << "(initDeviceInfo): add addr=" << ModbusRTU::addr2str(a) mbinfo << myname << "(initDeviceInfo): add addr=" << ModbusRTU::addr2str(a)
<< " ask_every_reg=" << d->second->ask_every_reg << endl; << " ask_every_reg=" << dev->ask_every_reg << endl;
string s(it.getProp("respondSensor")); string s(it.getProp("respondSensor"));
if( !s.empty() ) if( !s.empty() )
{ {
d->second->resp_id = uniset_conf()->getSensorID(s); dev->resp_id = uniset_conf()->getSensorID(s);
if( d->second->resp_id == DefaultObjectId ) if( dev->resp_id == DefaultObjectId )
{ {
mbinfo << myname << "(initDeviceInfo): not found ID for respondSensor=" << s << endl; mbinfo << myname << "(initDeviceInfo): not found ID for respondSensor=" << s << endl;
return false; return false;
...@@ -2786,15 +2914,15 @@ namespace uniset ...@@ -2786,15 +2914,15 @@ namespace uniset
if( !mod.empty() ) if( !mod.empty() )
{ {
d->second->mode_id = conf->getSensorID(mod); dev->mode_id = conf->getSensorID(mod);
if( d->second->mode_id == DefaultObjectId ) if( dev->mode_id == DefaultObjectId )
{ {
mbcrit << myname << "(initDeviceInfo): not found ID for modeSensor=" << mod << endl; mbcrit << myname << "(initDeviceInfo): not found ID for modeSensor=" << mod << endl;
return false; return false;
} }
UniversalIO::IOType m_iotype = conf->getIOType(d->second->mode_id); UniversalIO::IOType m_iotype = conf->getIOType(dev->mode_id);
if( m_iotype != UniversalIO::AI ) if( m_iotype != UniversalIO::AI )
{ {
...@@ -2803,15 +2931,35 @@ namespace uniset ...@@ -2803,15 +2931,35 @@ namespace uniset
} }
} }
string safemode(it.getProp("safemodeSensor"));
if( !safemode.empty() )
{
dev->safemode_id = conf->getSensorID(safemode);
if( dev->safemode_id == DefaultObjectId )
{
mbcrit << myname << "(initDeviceInfo): not found ID for safemodeSensor=" << safemode << endl;
return false;
}
string safemodeValue(it.getProp("safemodeValue"));
if( !safemodeValue.empty() )
dev->safemode_value = uni_atoi(safemodeValue);
dev->safeMode = MBExchange::safeExternalControl;
}
mbinfo << myname << "(initDeviceInfo): add addr=" << ModbusRTU::addr2str(a) << endl; mbinfo << myname << "(initDeviceInfo): add addr=" << ModbusRTU::addr2str(a) << endl;
int tout = it.getPIntProp("timeout", default_timeout ); int tout = it.getPIntProp("timeout", default_timeout );
d->second->resp_Delay.set(0, tout); dev->resp_Delay.set(0, tout);
d->second->resp_invert = it.getIntProp("invert"); dev->resp_invert = it.getIntProp("invert");
d->second->resp_force = it.getIntProp("force"); dev->resp_force = it.getIntProp("force");
int init_tout = it.getPIntProp("respondInitTimeout", tout); int init_tout = it.getPIntProp("respondInitTimeout", tout);
d->second->resp_ptInit.setTiming(init_tout); dev->resp_ptInit.setTiming(init_tout);
return true; return true;
} }
...@@ -2868,16 +3016,16 @@ namespace uniset ...@@ -2868,16 +3016,16 @@ namespace uniset
msleep(initPause); msleep(initPause);
PassiveTimer ptAct(activateTimeout); PassiveTimer ptAct(activateTimeout);
while( !checkProcActive() && !ptAct.checkTime() ) while( !isProcActive() && !ptAct.checkTime() )
{ {
cout << myname << "(sysCommand): wait activate..." << endl; cout << myname << "(sysCommand): wait activate..." << endl;
msleep(300); msleep(300);
if( checkProcActive() ) if( isProcActive() )
break; break;
} }
if( !checkProcActive() ) if( !isProcActive() )
mbcrit << myname << "(sysCommand): ************* don`t activate?! ************" << endl; mbcrit << myname << "(sysCommand): ************* don`t activate?! ************" << endl;
{ {
...@@ -2952,7 +3100,7 @@ namespace uniset ...@@ -2952,7 +3100,7 @@ namespace uniset
<< activateTimeout << " мсек"; << activateTimeout << " мсек";
mbcrit << err.str() << endl; mbcrit << err.str() << endl;
kill(SIGTERM, getpid()); // прерываем (перезапускаем) процесс... std::terminate(); // прерываем (перезапускаем) процесс...
// throw SystemError(err.str()); // throw SystemError(err.str());
return; return;
} }
...@@ -2971,20 +3119,6 @@ namespace uniset ...@@ -2971,20 +3119,6 @@ namespace uniset
mbwarn << myname << "(askSensors): 'sidExchangeMode' catch..." << std::endl; mbwarn << myname << "(askSensors): 'sidExchangeMode' catch..." << std::endl;
} }
try
{
if( sidSafeModeExternal != DefaultObjectId )
shm->askSensor(sidSafeModeExternal, cmd);
}
catch( uniset::Exception& ex )
{
mbwarn << myname << "(askSensors): " << ex << std::endl;
}
catch(...)
{
mbwarn << myname << "(askSensors): 'sidSafeModeExternal' catch..." << std::endl;
}
for( auto it1 = devices.begin(); it1 != devices.end(); ++it1 ) for( auto it1 = devices.begin(); it1 != devices.end(); ++it1 )
{ {
auto d = it1->second; auto d = it1->second;
...@@ -2993,6 +3127,9 @@ namespace uniset ...@@ -2993,6 +3127,9 @@ namespace uniset
{ {
if( d->mode_id != DefaultObjectId ) if( d->mode_id != DefaultObjectId )
shm->askSensor(d->mode_id, cmd); shm->askSensor(d->mode_id, cmd);
if( d->safemode_id != DefaultObjectId )
shm->askSensor(d->safemode_id, cmd);
} }
catch( uniset::Exception& ex ) catch( uniset::Exception& ex )
{ {
...@@ -3000,7 +3137,11 @@ namespace uniset ...@@ -3000,7 +3137,11 @@ namespace uniset
} }
catch(...) catch(...)
{ {
mbwarn << myname << "(askSensors): (mode_id=" << d->mode_id << ").. catch..." << std::endl; mbwarn << myname << "(askSensors): "
<< "("
<< " mode_id=" << d->mode_id
<< " safemode_id=" << d->safemode_id
<< ").. catch..." << std::endl;
} }
if( force_out ) if( force_out )
...@@ -3046,11 +3187,19 @@ namespace uniset ...@@ -3046,11 +3187,19 @@ namespace uniset
for( auto it1 = devices.begin(); it1 != devices.end(); ++it1 ) for( auto it1 = devices.begin(); it1 != devices.end(); ++it1 )
{ {
auto d(it1->second); auto& d(it1->second);
if( sm->id == d->mode_id ) if( sm->id == d->mode_id )
d->mode = sm->value; d->mode = sm->value;
if( sm->id == d->safemode_id )
{
if( sm->value == d->safemode_value )
d->safeMode = safeExternalControl;
else
d->safeMode = safeNone;
}
if( force_out ) if( force_out )
continue; continue;
...@@ -3102,7 +3251,7 @@ namespace uniset ...@@ -3102,7 +3251,7 @@ namespace uniset
{ {
mb = initMB(false); mb = initMB(false);
if( !checkProcActive() ) if( !isProcActive() )
return false; return false;
updateSM(); updateSM();
...@@ -3118,7 +3267,7 @@ namespace uniset ...@@ -3118,7 +3267,7 @@ namespace uniset
if( !allInitOK ) if( !allInitOK )
firstInitRegisters(); firstInitRegisters();
if( !checkProcActive() ) if( !isProcActive() )
return false; return false;
ncycle++; ncycle++;
...@@ -3145,7 +3294,7 @@ namespace uniset ...@@ -3145,7 +3294,7 @@ namespace uniset
for( auto it = regmap->begin(); it != regmap->end(); ++it ) for( auto it = regmap->begin(); it != regmap->end(); ++it )
{ {
if( !checkProcActive() ) if( !isProcActive() )
return false; return false;
if( exchangeMode == emSkipExchange ) if( exchangeMode == emSkipExchange )
...@@ -3177,7 +3326,7 @@ namespace uniset ...@@ -3177,7 +3326,7 @@ namespace uniset
if( it == regmap->end() ) if( it == regmap->end() )
break; break;
if( !checkProcActive() ) if( !isProcActive() )
return false; return false;
} }
} }
...@@ -3196,7 +3345,7 @@ namespace uniset ...@@ -3196,7 +3345,7 @@ namespace uniset
poll_count = 0; poll_count = 0;
} }
if( !checkProcActive() ) if( !isProcActive() )
return false; return false;
// update SharedMemory... // update SharedMemory...
...@@ -3205,7 +3354,7 @@ namespace uniset ...@@ -3205,7 +3354,7 @@ namespace uniset
// check thresholds // check thresholds
for( auto t = thrlist.begin(); t != thrlist.end(); ++t ) for( auto t = thrlist.begin(); t != thrlist.end(); ++t )
{ {
if( !checkProcActive() ) if( !isProcActive() )
return false; return false;
IOBase::processingThreshold(&(*t), shm, force); IOBase::processingThreshold(&(*t), shm, force);
...@@ -3338,18 +3487,23 @@ namespace uniset ...@@ -3338,18 +3487,23 @@ namespace uniset
return os; return os;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
ostream& operator<<( ostream& os, const MBExchange::SafeMode& sm ) std::string to_string( const MBExchange::SafeMode & m )
{ {
if( sm == MBExchange::safeNone ) if( m == MBExchange::safeNone )
return os << "safeNone"; return "safeNone";
if( sm == MBExchange::safeResetIfNotRespond ) if( m == MBExchange::safeResetIfNotRespond )
return os << "safeResetIfNotRespond"; return "safeResetIfNotRespond";
if( sm == MBExchange::safeExternalControl ) if( m == MBExchange::safeExternalControl )
return os << "safeExternalControl"; return "safeExternalControl";
return os; return "";
}
ostream& operator<<( ostream& os, const MBExchange::SafeMode& m )
{
return os << to_string(m);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
uniset::SimpleInfo* MBExchange::getInfo( const char* userparam ) uniset::SimpleInfo* MBExchange::getInfo( const char* userparam )
......
...@@ -63,8 +63,6 @@ namespace uniset ...@@ -63,8 +63,6 @@ namespace uniset
/*! глобальная функция для вывода help-а */ /*! глобальная функция для вывода help-а */
static void help_print( int argc, const char* const* argv ); static void help_print( int argc, const char* const* argv );
static const int NoSafetyState = -1;
/*! Режимы работы процесса обмена */ /*! Режимы работы процесса обмена */
enum ExchangeMode enum ExchangeMode
{ {
...@@ -84,7 +82,9 @@ namespace uniset ...@@ -84,7 +82,9 @@ namespace uniset
safeExternalControl = 2 /*!< управление сбросом по внешнему датчику */ safeExternalControl = 2 /*!< управление сбросом по внешнему датчику */
}; };
friend std::ostream& operator<<( std::ostream& os, const SafeMode& em );
friend std::string to_string( const SafeMode & m );
friend std::ostream& operator<<( std::ostream& os, const SafeMode& m );
enum DeviceType enum DeviceType
{ {
...@@ -139,33 +139,26 @@ namespace uniset ...@@ -139,33 +139,26 @@ namespace uniset
RegInfo& operator=(const RegInfo& r) = delete; RegInfo& operator=(const RegInfo& r) = delete;
RegInfo( RegInfo&& r ) = delete; RegInfo( RegInfo&& r ) = delete;
RegInfo& operator=(RegInfo&& r) = default; RegInfo& operator=(RegInfo&& r) = default;
RegInfo() = default;
RegInfo(): ModbusRTU::ModbusData mbval = { 0 };
mbval(0), mbreg(0), mbfunc(ModbusRTU::fnUnknown), ModbusRTU::ModbusData mbreg = { 0 }; /*!< регистр */
id(0), dev(0), ModbusRTU::SlaveFunctionCode mbfunc = { ModbusRTU::fnUnknown }; /*!< функция для чтения/записи */
rtuJack(RTUStorage::nUnknown), rtuChan(0),
mtrType(MTR::mtUnknown),
q_num(0), q_count(1), mb_initOK(false), sm_initOK(false)
{}
ModbusRTU::ModbusData mbval;
ModbusRTU::ModbusData mbreg; /*!< регистр */
ModbusRTU::SlaveFunctionCode mbfunc; /*!< функция для чтения/записи */
PList slst; PList slst;
ModbusRTU::RegID id; ModbusRTU::RegID id = { 0 };
std::shared_ptr<RTUDevice> dev; std::shared_ptr<RTUDevice> dev;
// only for RTU188 // only for RTU188
RTUStorage::RTUJack rtuJack; RTUStorage::RTUJack rtuJack = { RTUStorage::nUnknown };
int rtuChan; int rtuChan = { 0 };
// only for MTR // only for MTR
MTR::MTRType mtrType; /*!< тип регистра (согласно спецификации на MTR) */ MTR::MTRType mtrType = { MTR::mtUnknown }; /*!< тип регистра (согласно спецификации на MTR) */
// optimization // optimization
size_t q_num; /*!< number in query */ size_t q_num = { 0 }; /*!< number in query */
size_t q_count; /*!< count registers for query */ size_t q_count = { 0 }; /*!< count registers for query */
RegMap::iterator rit; RegMap::iterator rit;
...@@ -174,11 +167,11 @@ namespace uniset ...@@ -174,11 +167,11 @@ namespace uniset
// Если tcp_preinit="1", то сперва будет сделано чтение значения из устройства. // Если tcp_preinit="1", то сперва будет сделано чтение значения из устройства.
// при этом флаг mb_init=false пока не пройдёт успешной инициализации // при этом флаг mb_init=false пока не пройдёт успешной инициализации
// Если tcp_preinit="0", то флаг mb_init сразу выставляется в true. // Если tcp_preinit="0", то флаг mb_init сразу выставляется в true.
bool mb_initOK; /*!< инициализировалось ли значение из устройства */ bool mb_initOK = { false }; /*!< инициализировалось ли значение из устройства */
// Флаг sm_init означает, что писать в устройство нельзя, т.к. значение в "карте регистров" // Флаг sm_init означает, что писать в устройство нельзя, т.к. значение в "карте регистров"
// ещё не инициализировано из SM // ещё не инициализировано из SM
bool sm_initOK; /*!< инициализировалось ли значение из SM */ bool sm_initOK = { false }; /*!< инициализировалось ли значение из SM */
}; };
friend std::ostream& operator<<( std::ostream& os, RegInfo& r ); friend std::ostream& operator<<( std::ostream& os, RegInfo& r );
...@@ -186,52 +179,42 @@ namespace uniset ...@@ -186,52 +179,42 @@ namespace uniset
struct RTUDevice struct RTUDevice
{ {
RTUDevice(): ModbusRTU::ModbusAddr mbaddr = { 0 }; /*!< адрес устройства */
mbaddr(0),
dtype(dtUnknown),
resp_id(uniset::DefaultObjectId),
resp_state(false),
resp_invert(false),
numreply(0),
prev_numreply(0),
ask_every_reg(false),
mode_id(uniset::DefaultObjectId),
mode(emNone),
speed(ComPort::ComSpeed38400),
rtu188(0)
{
}
ModbusRTU::ModbusAddr mbaddr; /*!< адрес устройства */
std::unordered_map<size_t, std::shared_ptr<RegMap>> pollmap; std::unordered_map<size_t, std::shared_ptr<RegMap>> pollmap;
DeviceType dtype; /*!< тип устройства */ DeviceType dtype = { dtUnknown }; /*!< тип устройства */
// resp - respond..(контроль наличия связи) // resp - respond..(контроль наличия связи)
uniset::ObjectId resp_id; uniset::ObjectId resp_id = { uniset::DefaultObjectId };
IOController::IOStateList::iterator resp_it; IOController::IOStateList::iterator resp_it;
DelayTimer resp_Delay; // таймер для формирования задержки на отпускание (пропадание связи) DelayTimer resp_Delay; // таймер для формирования задержки на отпускание (пропадание связи)
PassiveTimer resp_ptInit; // таймер для формирования задержки на инициализацию связи (задержка на выставление датчика связи после запуска) PassiveTimer resp_ptInit; // таймер для формирования задержки на инициализацию связи (задержка на выставление датчика связи после запуска)
bool resp_state; bool resp_state = { false };
bool resp_invert; bool resp_invert = { false };
bool resp_force = { false }; bool resp_force = { false };
Trigger trInitOK; // триггер для "инициализации" Trigger trInitOK; // триггер для "инициализации"
std::atomic<size_t> numreply; // количество успешных запросов.. std::atomic<size_t> numreply = { 0 }; // количество успешных запросов..
std::atomic<size_t> prev_numreply; std::atomic<size_t> prev_numreply = { 0 };
// //
bool ask_every_reg; /*!< опрашивать ли каждый регистр, независимо от результата опроса предыдущего. По умолчанию false - прервать опрос при первом же timeout */ bool ask_every_reg = { false }; /*!< опрашивать ли каждый регистр, независимо от результата опроса предыдущего. По умолчанию false - прервать опрос при первом же timeout */
// режим работы // режим работы
uniset::ObjectId mode_id; uniset::ObjectId mode_id = { uniset::DefaultObjectId };
IOController::IOStateList::iterator mode_it; IOController::IOStateList::iterator mode_it;
long mode; // режим работы с устройством (см. ExchangeMode) long mode = { emNone }; // режим работы с устройством (см. ExchangeMode)
// safe mode
long safeMode = { safeNone }; /*!< режим безопасного состояния см. SafeMode */
uniset::ObjectId safemode_id = { uniset::DefaultObjectId }; /*!< иденидентификатор для датчика безопасного режима */
IOController::IOStateList::iterator safemode_it;
long safemode_value = { 1 };
// return TRUE if state changed // return TRUE if state changed
bool checkRespond( std::shared_ptr<DebugStream>& log ); bool checkRespond( std::shared_ptr<DebugStream>& log );
// специфические поля для RS // специфические поля для RS
ComPort::Speed speed; ComPort::Speed speed = { ComPort::ComSpeed38400 };
std::shared_ptr<RTUStorage> rtu188; std::shared_ptr<RTUStorage> rtu188;
std::string getShortInfo() const; std::string getShortInfo() const;
...@@ -298,7 +281,6 @@ namespace uniset ...@@ -298,7 +281,6 @@ namespace uniset
RTUDeviceMap devices; RTUDeviceMap devices;
InitList initRegList; /*!< список регистров для инициализации */ InitList initRegList; /*!< список регистров для инициализации */
// uniset::uniset_rwmutex pollMutex;
virtual std::shared_ptr<ModbusClient> initMB( bool reopen = false ) = 0; virtual std::shared_ptr<ModbusClient> initMB( bool reopen = false ) = 0;
...@@ -312,10 +294,11 @@ namespace uniset ...@@ -312,10 +294,11 @@ namespace uniset
void updateRSProperty( RSProperty* p, bool write_only = false ); void updateRSProperty( RSProperty* p, bool write_only = false );
virtual void updateRespondSensors(); virtual void updateRespondSensors();
bool checkUpdateSM( bool wrFunc, long devMode ); bool isUpdateSM( bool wrFunc, long devMode ) const noexcept;
bool checkPoll( bool wrFunc ) const; bool isPollEnabled( bool wrFunc ) const noexcept;
bool isSafeMode( std::shared_ptr<RTUDevice>& dev ) const noexcept;
bool checkProcActive() const; bool isProcActive() const;
void setProcActive( bool st ); void setProcActive( bool st );
void waitSMReady(); void waitSMReady();
...@@ -353,7 +336,7 @@ namespace uniset ...@@ -353,7 +336,7 @@ namespace uniset
bool force_out = { false }; /*!< флаг означающий, принудительного чтения выходов */ bool force_out = { false }; /*!< флаг означающий, принудительного чтения выходов */
bool mbregFromID = { false }; bool mbregFromID = { false };
timeout_t polltime = { 100 }; /*!< переодичность обновления данных, [мсек] */ timeout_t polltime = { 100 }; /*!< переодичность обновления данных, [мсек] */
timeout_t sleepPause_msec; timeout_t sleepPause_msec = { 10 };
size_t maxQueryCount = { ModbusRTU::MAXDATALEN }; /*!< максимальное количество регистров для одного запроса */ size_t maxQueryCount = { ModbusRTU::MAXDATALEN }; /*!< максимальное количество регистров для одного запроса */
PassiveTimer ptHeartBeat; PassiveTimer ptHeartBeat;
...@@ -364,12 +347,7 @@ namespace uniset ...@@ -364,12 +347,7 @@ namespace uniset
uniset::ObjectId sidExchangeMode = { uniset::DefaultObjectId }; /*!< иденидентификатор для датчика режима работы */ uniset::ObjectId sidExchangeMode = { uniset::DefaultObjectId }; /*!< иденидентификатор для датчика режима работы */
IOController::IOStateList::iterator itExchangeMode; IOController::IOStateList::iterator itExchangeMode;
long exchangeMode = {emNone}; /*!< режим работы см. ExchangeMode */ long exchangeMode = { emNone }; /*!< режим работы см. ExchangeMode */
long safeMode = { safeNone }; /*!< режим безопасного состояния см. SafeMode */
uniset::ObjectId sidSafeModeExternal = { uniset::DefaultObjectId }; /*!< иденидентификатор для датчика безопасного режима */
IOController::IOStateList::iterator itSafeModeExternal;
long valueSafeModeExternal = { 1 };
std::atomic_bool activated = { false }; std::atomic_bool activated = { false };
timeout_t activateTimeout = { 20000 }; // msec timeout_t activateTimeout = { 20000 }; // msec
......
...@@ -150,13 +150,13 @@ void MBTCPMaster::final_thread() ...@@ -150,13 +150,13 @@ void MBTCPMaster::final_thread()
void MBTCPMaster::poll_thread() void MBTCPMaster::poll_thread()
{ {
// ждём начала работы..(см. MBExchange::activateObject) // ждём начала работы..(см. MBExchange::activateObject)
while( !checkProcActive() ) while( !isProcActive() )
{ {
uniset::uniset_rwmutex_rlock l(mutex_start); uniset::uniset_rwmutex_rlock l(mutex_start);
} }
// работаем // работаем
while( checkProcActive() ) while( isProcActive() )
{ {
try try
{ {
...@@ -178,7 +178,7 @@ void MBTCPMaster::poll_thread() ...@@ -178,7 +178,7 @@ void MBTCPMaster::poll_thread()
throw; throw;
} }
if( !checkProcActive() ) if( !isProcActive() )
break; break;
msleep(polltime); msleep(polltime);
......
...@@ -463,13 +463,13 @@ void MBTCPMultiMaster::sysCommand( const uniset::SystemMessage* sm ) ...@@ -463,13 +463,13 @@ void MBTCPMultiMaster::sysCommand( const uniset::SystemMessage* sm )
void MBTCPMultiMaster::poll_thread() void MBTCPMultiMaster::poll_thread()
{ {
// ждём начала работы..(см. MBExchange::activateObject) // ждём начала работы..(см. MBExchange::activateObject)
while( !checkProcActive() ) while( !isProcActive() )
{ {
uniset::uniset_rwmutex_rlock l(mutex_start); uniset::uniset_rwmutex_rlock l(mutex_start);
} }
// работаем.. // работаем..
while( checkProcActive() ) while( isProcActive() )
{ {
try try
{ {
...@@ -490,7 +490,7 @@ void MBTCPMultiMaster::poll_thread() ...@@ -490,7 +490,7 @@ void MBTCPMultiMaster::poll_thread()
mbwarn << myname << "(poll_thread): " << ex.what() << endl; mbwarn << myname << "(poll_thread): " << ex.what() << endl;
} }
if( !checkProcActive() ) if( !isProcActive() )
break; break;
msleep(polltime); msleep(polltime);
...@@ -499,7 +499,7 @@ void MBTCPMultiMaster::poll_thread() ...@@ -499,7 +499,7 @@ void MBTCPMultiMaster::poll_thread()
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBTCPMultiMaster::check_thread() void MBTCPMultiMaster::check_thread()
{ {
while( checkProcActive() ) while( isProcActive() )
{ {
for( auto && it : mblist ) for( auto && it : mblist )
{ {
...@@ -520,7 +520,7 @@ void MBTCPMultiMaster::check_thread() ...@@ -520,7 +520,7 @@ void MBTCPMultiMaster::check_thread()
<< " respond_force=" << it->respond_force << " respond_force=" << it->respond_force
<< " respond=" << it->respond << " respond=" << it->respond
<< " respond_invert=" << it->respond_invert << " respond_invert=" << it->respond_invert
<< " activated=" << checkProcActive() << " activated=" << isProcActive()
<< " ]" << " ]"
<< endl; << endl;
...@@ -528,7 +528,7 @@ void MBTCPMultiMaster::check_thread() ...@@ -528,7 +528,7 @@ void MBTCPMultiMaster::check_thread()
if( it->respond_init ) if( it->respond_init )
r = it->respondDelay.check( r ); r = it->respondDelay.check( r );
if( !checkProcActive() ) if( !isProcActive() )
break; break;
try try
...@@ -560,11 +560,11 @@ void MBTCPMultiMaster::check_thread() ...@@ -560,11 +560,11 @@ void MBTCPMultiMaster::check_thread()
mbcrit << myname << "(check): (respond) " << it->myname << " : " << ex.what() << std::endl; mbcrit << myname << "(check): (respond) " << it->myname << " : " << ex.what() << std::endl;
} }
if( !checkProcActive() ) if( !isProcActive() )
break; break;
} }
if( !checkProcActive() ) if( !isProcActive() )
break; break;
msleep(checktime); msleep(checktime);
......
...@@ -78,6 +78,8 @@ namespace uniset ...@@ -78,6 +78,8 @@ namespace uniset
- \b force [1,0] - "1" - обновлять значение датчика связи в SM принудительно на каждом цикле проверки ("0" - только по изменению). - \b force [1,0] - "1" - обновлять значение датчика связи в SM принудительно на каждом цикле проверки ("0" - только по изменению).
- \b exchangeModeID - идентификатор датчика режима работы (см. MBExchange::ExchangeMode). - \b exchangeModeID - идентификатор датчика режима работы (см. MBExchange::ExchangeMode).
- \b ask_every_reg - 1 - опрашивать ВСЕ регистры подряд, не обращая внимания на timeout. По умолчанию - "0" Т.е. опрос устройства (на текущем шаге цикла опроса), прерывается на первом же регистре, при опросе которого возникнет timeout. - \b ask_every_reg - 1 - опрашивать ВСЕ регистры подряд, не обращая внимания на timeout. По умолчанию - "0" Т.е. опрос устройства (на текущем шаге цикла опроса), прерывается на первом же регистре, при опросе которого возникнет timeout.
- \b safemodeSensor - датчик для управления "безопасным режимом". см. \ref MBTCPM_SafeMode
- \b safemodeSensorValue - значение датчика, при котором происходит сброс в "безопасные значения"
Секция <GateList> позволяет задать несколько каналов связи со Slave-устройством. Это удобно для случая, когда Slave имеет Секция <GateList> позволяет задать несколько каналов связи со Slave-устройством. Это удобно для случая, когда Slave имеет
более одного канала связи с ним (основной и резервный например). более одного канала связи с ним (основной и резервный например).
......
...@@ -201,7 +201,7 @@ bool RTUExchange::poll() ...@@ -201,7 +201,7 @@ bool RTUExchange::poll()
{ {
mb = initMB(false); mb = initMB(false);
if( !checkProcActive() ) if( !isProcActive() )
return false; return false;
updateSM(); updateSM();
...@@ -212,7 +212,7 @@ bool RTUExchange::poll() ...@@ -212,7 +212,7 @@ bool RTUExchange::poll()
if( !allInitOK ) if( !allInitOK )
firstInitRegisters(); firstInitRegisters();
if( !checkProcActive() ) if( !isProcActive() )
return false; return false;
ncycle++; ncycle++;
...@@ -301,7 +301,7 @@ bool RTUExchange::poll() ...@@ -301,7 +301,7 @@ bool RTUExchange::poll()
if( it == rmap->end() ) if( it == rmap->end() )
break; break;
if( !checkProcActive() ) if( !isProcActive() )
return false; return false;
} }
} }
...@@ -314,7 +314,7 @@ bool RTUExchange::poll() ...@@ -314,7 +314,7 @@ bool RTUExchange::poll()
// check thresholds // check thresholds
for( auto && t : thrlist ) for( auto && t : thrlist )
{ {
if( !checkProcActive() ) if( !isProcActive() )
return false; return false;
IOBase::processingThreshold(&t, shm, force); IOBase::processingThreshold(&t, shm, force);
......
...@@ -29,12 +29,12 @@ ...@@ -29,12 +29,12 @@
<SharedMemory name="SharedMemory" shmID="SharedMemory"/> <SharedMemory name="SharedMemory" shmID="SharedMemory"/>
<MBTCPMaster1 name="MBTCPMaster1" exchangeModeID="MBTCPMaster_Mode_AS"> <MBTCPMaster1 name="MBTCPMaster1" exchangeModeID="MBTCPMaster_Mode_AS">
<DeviceList> <DeviceList>
<item addr="0x01" invert="1" respondSensor="Slave_Not_Respond_S" timeout="1000"/> <item addr="0x01" invert="1" respondSensor="Slave_Not_Respond_S" timeout="1000" safemodeSensor="Slave1_SafemodeSensor_S" safemodeValue="42"/>
</DeviceList> </DeviceList>
</MBTCPMaster1> </MBTCPMaster1>
<MBTCPMultiMaster1 name="MBTCPMultiMaster1" poll_time="200" reply_timeout="60"> <MBTCPMultiMaster1 name="MBTCPMultiMaster1" poll_time="200" reply_timeout="60">
<DeviceList> <DeviceList>
<item addr="0x01" invert="1" respondSensor="Slave_Not_Respond_S" timeout="1000"/> <item addr="0x01" invert="1" respondSensor="Slave_Not_Respond_S" timeout="1000" safemodeSensor="Slave1_SafemodeSensor_S" safemodeValue="42" />
</DeviceList> </DeviceList>
<GateList> <GateList>
<item ip="127.0.0.1" port="20053" recv_timeout="200" invert="1" respondSensor="Slave1_Not_Respond_S"/> <item ip="127.0.0.1" port="20053" recv_timeout="200" invert="1" respondSensor="Slave1_Not_Respond_S"/>
...@@ -114,6 +114,11 @@ ...@@ -114,6 +114,11 @@
<item id="1027" mb="2" mbtype="rtu" mbaddr="0x01" mbreg="41" mbfunc="0x10" vtype="F2" iotype="AO" name="TestWrite1027_F2" precision="1" textname="F2: Тестовый регистр для 0x10"/> <item id="1027" mb="2" mbtype="rtu" mbaddr="0x01" mbreg="41" mbfunc="0x10" vtype="F2" iotype="AO" name="TestWrite1027_F2" precision="1" textname="F2: Тестовый регистр для 0x10"/>
<item id="1028" mb="2" mbtype="rtu" mbaddr="0x01" mbreg="47" mbfunc="0x03" vtype="F2" iotype="DI" name="TestWrite1028_F2" textname="F2: Тестовый регистр для 0x10"/> <item id="1028" mb="2" mbtype="rtu" mbaddr="0x01" mbreg="47" mbfunc="0x03" vtype="F2" iotype="DI" name="TestWrite1028_F2" textname="F2: Тестовый регистр для 0x10"/>
<!-- SafeMode tests -->
<item id="1040" name="Slave1_SafemodeSensor_S" iotype="AI" textname="Управление safeMode" />
<item id="1041" safeval="42" mb="1" mbtype="rtu" mbaddr="0x01" mbreg="10" mbfunc="0x03" iotype="AI" name="SafeMode_TestRead03" textname="(safemode): Тестовый регистр для 0x03"/>
<item id="1042" safeval="1" mb="1" mbtype="rtu" mbaddr="0x01" mbreg="11" mbfunc="0x02" iotype="DI" name="SafeMode_TestRead02" textname="(safemode): Тестовый регистр для 0x02"/>
<item id="10000" iotype="DI" name="TestMode_S" textname="Тестовый датчик"/> <item id="10000" iotype="DI" name="TestMode_S" textname="Тестовый датчик"/>
</sensors> </sensors>
......
...@@ -681,6 +681,34 @@ TEST_CASE("MBTCPMaster: 0x66 (file transfer)", "[modbus][0x66][mbmaster][mbtcpma ...@@ -681,6 +681,34 @@ TEST_CASE("MBTCPMaster: 0x66 (file transfer)", "[modbus][0x66][mbmaster][mbtcpma
WARN("Test of '0x66'..not yet.. "); WARN("Test of '0x66'..not yet.. ");
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
TEST_CASE("MBTCPMaster: safe mode", "[modbus][safemode][mbmaster][mbtcpmaster]")
{
InitTest();
smi->setValue(1040,0); // отключаем safeMode
mbs->setReply(50);
msleep(polltime + 200);
REQUIRE( ui->getValue(1041) == 50 );
// REQUIRE( ui->getValue(1042) == 1 );
mbs->setReply(0);
msleep(polltime + 200);
REQUIRE( ui->getValue(1041) == 0 );
REQUIRE( ui->getValue(1042) == 0 );
smi->setValue(1040,42); // включаем safeMode
msleep(polltime + 200);
REQUIRE( ui->getValue(1041) == 42 );
REQUIRE( ui->getValue(1042) == 1 );
smi->setValue(1040,0); // отключаем safeMode
mbs->setReply(0);
msleep(polltime + 200);
REQUIRE( ui->getValue(1041) == 0 );
REQUIRE( ui->getValue(1042) == 0 );
}
// -----------------------------------------------------------------------------
#if 0 #if 0
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
static bool init_iobase( IOBase* ib, const std::string& sensor ) static bool init_iobase( IOBase* ib, const std::string& sensor )
......
...@@ -151,3 +151,31 @@ TEST_CASE("MBTCPMultiMaster: rotate channel", "[modbus][mbmaster][mbtcpmultimast ...@@ -151,3 +151,31 @@ TEST_CASE("MBTCPMultiMaster: rotate channel", "[modbus][mbmaster][mbtcpmultimast
REQUIRE( ui->getValue(1003) == 100 ); REQUIRE( ui->getValue(1003) == 100 );
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
TEST_CASE("MBTCPMultiMaster: safe mode", "[modbus][safemode][mbmaster][mbtcpmultimaster]")
{
InitTest();
ui->setValue(1040,0); // отключаем safeMode
mbs1->setReply(50);
msleep(polltime + 200);
REQUIRE( ui->getValue(1041) == 50 );
// REQUIRE( ui->getValue(1042) == 1 );
mbs1->setReply(0);
msleep(polltime + 200);
REQUIRE( ui->getValue(1041) == 0 );
REQUIRE( ui->getValue(1042) == 0 );
ui->setValue(1040,42); // включаем safeMode
msleep(polltime + 200);
REQUIRE( ui->getValue(1041) == 42 );
REQUIRE( ui->getValue(1042) == 1 );
ui->setValue(1040,0); // отключаем safeMode
mbs1->setReply(0);
msleep(polltime + 200);
REQUIRE( ui->getValue(1041) == 0 );
REQUIRE( ui->getValue(1042) == 0 );
}
// -----------------------------------------------------------------------------
...@@ -35,7 +35,6 @@ namespace uniset ...@@ -35,7 +35,6 @@ namespace uniset
{ {
static const int DefaultSubdev = -1; static const int DefaultSubdev = -1;
static const int DefaultChannel = -1; static const int DefaultChannel = -1;
static const int UnusedSafeValue = -1; // значение обозначающее, не использовать safe value
// т.к. IOBase содержит rwmutex с запрещённым конструктором копирования // т.к. IOBase содержит rwmutex с запрещённым конструктором копирования
// приходится здесь тоже объявлять разрешенными только операции "перемещения" // приходится здесь тоже объявлять разрешенными только операции "перемещения"
...@@ -108,8 +107,9 @@ namespace uniset ...@@ -108,8 +107,9 @@ namespace uniset
long value; /*!< текущее значение */ long value; /*!< текущее значение */
long craw; /*!< текущее 'сырое' значение до калибровки */ long craw; /*!< текущее 'сырое' значение до калибровки */
long cprev; /*!< предыдущее значение после калибровки */ long cprev; /*!< предыдущее значение после калибровки */
long safeval; /*!< безопасное значение */ long safeval; /*!< безопасное значение */
long defval; /*!< состояние по умолчанию (при запуске) */ long defval; /*!< состояние по умолчанию (при запуске) */
bool safevalDefined = { false }; /*!< флаг, означающий что safeval задан (можно использовать) */
DigitalFilter df; /*!< реализация программного фильтра */ DigitalFilter df; /*!< реализация программного фильтра */
bool nofilter; /*!< отключение фильтра */ bool nofilter; /*!< отключение фильтра */
......
...@@ -632,7 +632,11 @@ namespace uniset ...@@ -632,7 +632,11 @@ namespace uniset
} }
} }
b->safeval = initIntProp(it, "safeval", prefix, init_prefix_only, UnusedSafeValue); std::string ssafe = initProp(it, "safeval", prefix, init_prefix_only);
b->safevalDefined = !ssafe.empty();
if( b->safevalDefined )
b->safeval = uni_atoi(ssafe);
b->stype = uniset::getIOType(initProp(it, "iotype", prefix, init_prefix_only)); b->stype = uniset::getIOType(initProp(it, "iotype", prefix, init_prefix_only));
...@@ -815,6 +819,7 @@ namespace uniset ...@@ -815,6 +819,7 @@ namespace uniset
b.craw = craw; b.craw = craw;
b.cprev = cprev; b.cprev = cprev;
b.safeval = safeval; b.safeval = safeval;
b.safevalDefined = safevalDefined;
b.defval = defval; b.defval = defval;
b.df = df; b.df = df;
b.nofilter = nofilter; b.nofilter = nofilter;
...@@ -854,6 +859,7 @@ namespace uniset ...@@ -854,6 +859,7 @@ namespace uniset
craw = b.craw; craw = b.craw;
cprev = b.cprev; cprev = b.cprev;
safeval = b.safeval; safeval = b.safeval;
safevalDefined = b.safevalDefined;
defval = b.defval; defval = b.defval;
df = b.df; df = b.df;
nofilter = b.nofilter; nofilter = b.nofilter;
......
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