Commit 754a7b5e authored by Pavel Vainerman's avatar Pavel Vainerman

backported to p9 as 2.9.1-alt0.M90P.1 (with rpmbph script)

parents bb6930e3 2cad3bd5
......@@ -14,10 +14,10 @@ name: "CodeQL"
on:
push:
branches: [ master, github-actions ]
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
branches: [ "*" ]
schedule:
- cron: '44 6 * * 4'
......@@ -46,7 +46,9 @@ jobs:
- name: install packages
run: |
sudo apt-get install libcomedi-dev libpoco-dev libmysqlclient-dev libomniorb4-dev libev-dev omniidl xsltproc libpqxx3-dev librrd-dev libsigc++-2.0-dev libsqlite3-dev python-dev libmosquittopp-dev
sudo apt-get install libcomedi-dev libpoco-dev libmysqlclient-dev libomniorb4-dev \
libev-dev omniidl xsltproc libpqxx3-dev librrd-dev libsigc++-2.0-dev \
libsqlite3-dev python-dev libmosquittopp-dev libpoco-dev swig
wget https://github.com/catchorg/Catch2/releases/download/v1.11.0/catch.hpp -O include/catch.hpp
- name: build
......@@ -55,7 +57,7 @@ jobs:
# due broken comedi
export CXXFLAGS="$CXXFLAGS -Wl,--unresolved-symbols=ignore-in-shared-libs"
autoreconf -fiv
./configure --enable-mysql --enable-sqlite --enable-rrd --enable-io --disable-python --disable-mqtt --disable-pgsql --disable-api --disable-netdata --disable-logdb
./configure --disable-python --disable-netdata
make
- name: Perform CodeQL Analysis
......
name: C/C++ CI
name: testsuite
on:
push:
branches: [ master, github-actions ]
branches: [ "*" ]
pull_request:
branches: [ master ]
branches: [ "*" ]
jobs:
build:
runs-on: ubuntu-latest
container:
image: alt:sisyphus
steps:
- uses: actions/checkout@v2
- name: install packages
run: |
sudo apt-get install libcomedi-dev libpoco-dev libmysqlclient-dev libomniorb4-dev libev-dev omniidl xsltproc libpqxx3-dev librrd-dev libsigc++-2.0-dev libsqlite3-dev python-dev libmosquittopp-dev
wget https://github.com/catchorg/Catch2/releases/download/v1.11.0/catch.hpp -O include/catch.hpp
- name: configure
run: |
export CXXFLAGS='-pipe -O2 -pedantic -Wall'
# due broken comedi
export CXXFLAGS="$CXXFLAGS -Wl,--unresolved-symbols=ignore-in-shared-libs"
autoreconf -fiv
./configure --enable-mysql --enable-sqlite --enable-rrd --enable-io --disable-python --disable-mqtt --disable-pgsql --disable-api --disable-netdata --disable-logdb
- name: make
run: make
- name: simple tests
run: |
cd tests;
make check
- name: install packages
run: |
apt-get update && apt-get -y install etersoft-build-utils su sudo \
git-core ccache gcc-c++ etersoft-build-utils catch-devel \
libcomedi-devel libmariadb-devel libpqxx-devel librrd-devel libsqlite3-devel \
libxml2-devel libsigc++2-devel libpoco-devel libev-devel libomniORB-devel libmosquitto-devel \
xsltproc python-devel python-module-distribute libomniORB-names libomniORB-idl libomniORB-utils swig
- uses: actions/checkout@v2
- name: configure
run: |
export CXXFLAGS='-pipe -O2 -pedantic -Wall'
# due broken comedi
export CXXFLAGS="$CXXFLAGS -Wl,--unresolved-symbols=ignore-in-shared-libs"
autoreconf -fiv
./configure --disable-netdata
- name: make
run: make
- name: testsuite
run: |
cd testsuite;
make check
......@@ -10,32 +10,13 @@ env:
branches:
only:
- master
cache:
apt: true
matrix:
include:
- os: linux
# dist: precise
compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8']
env:
- MATRIX_EVAL="CXX=g++-4.8 CC=gcc-4.8"
- os: linux
compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.9']
env:
- MATRIX_EVAL="CXX=g++-4.9 CC=gcc-4.9"
- os: linux
compiler: gcc
addons:
apt:
......@@ -75,29 +56,11 @@ matrix:
compiler: clang
addons:
apt:
sources: ['llvm-toolchain-trusty-5.0']
packages: ['clang-5.0']
env:
- MATRIX_EVAL="CXX=clang++-5.0 CC=clang-5.0 COMPILER_NAME=clang"
- os: linux
compiler: clang
addons:
apt:
sources: ['llvm-toolchain-trusty-6.0', 'ubuntu-toolchain-r-test']
packages: ['clang-6.0']
env:
- MATRIX_EVAL="CXX=clang++-6.0 CC=clang-6.0 COMPILER_NAME=clang"
- os: linux
compiler: clang
addons:
apt:
sources: ['llvm-toolchain-trusty-7', 'ubuntu-toolchain-r-test']
packages: ['clang-7']
env:
- MATRIX_EVAL="CXX=clang++-7 CC=clang-7 COMPILER_NAME=clang"
# Disallowing packages: libcomedi-dev, libpoco-dev, libomniorb4-dev, libpqxx-dev, libev-dev
# If you require these packages, please review the package approval process at: https://github.com/travis-ci/apt-package-whitelist#package-approval-process
#sudo: false
......@@ -154,4 +117,4 @@ addons:
notification_email: lav@etersoft.ru
build_command_prepend: "make clean"
build_command: make -j4
branch_pattern: coverity_scan
branch_pattern: master
......@@ -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;
......
......@@ -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
......
......@@ -11,112 +11,112 @@
/*! Ничего не делающая реализация MBSlave для тестирования */
class MBSlave
{
public:
MBSlave( const std::unordered_set<uniset::ModbusRTU::ModbusAddr>& vaddr, const std::string& dev, const std::string& speed, bool use485 = false );
~MBSlave();
inline void setVerbose( bool state )
{
verbose = state;
}
inline void setReply( long val )
{
replyVal = val;
}
inline void setReply2( long val )
{
replyVal2 = val;
}
inline void setReply3( long val )
{
replyVal3 = val;
}
void execute(); /*!< основной цикл работы */
void setLog( std::shared_ptr<DebugStream> dlog );
protected:
// действия при завершении работы
void sigterm( int signo );
/*! обработка 0x01 */
uniset::ModbusRTU::mbErrCode readCoilStatus( uniset::ModbusRTU::ReadCoilMessage& query,
uniset::ModbusRTU::ReadCoilRetMessage& reply );
/*! обработка 0x02 */
uniset::ModbusRTU::mbErrCode readInputStatus( uniset::ModbusRTU::ReadInputStatusMessage& query,
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
/*! обработка 0x03 */
uniset::ModbusRTU::mbErrCode readOutputRegisters( uniset::ModbusRTU::ReadOutputMessage& query,
uniset::ModbusRTU::ReadOutputRetMessage& reply );
/*! обработка 0x04 */
uniset::ModbusRTU::mbErrCode readInputRegisters( uniset::ModbusRTU::ReadInputMessage& query,
uniset::ModbusRTU::ReadInputRetMessage& reply );
/*! обработка 0x05 */
uniset::ModbusRTU::mbErrCode forceSingleCoil( uniset::ModbusRTU::ForceSingleCoilMessage& query,
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
/*! обработка 0x0F */
uniset::ModbusRTU::mbErrCode forceMultipleCoils( uniset::ModbusRTU::ForceCoilsMessage& query,
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
/*! обработка 0x10 */
uniset::ModbusRTU::mbErrCode writeOutputRegisters( uniset::ModbusRTU::WriteOutputMessage& query,
uniset::ModbusRTU::WriteOutputRetMessage& reply );
/*! обработка 0x06 */
uniset::ModbusRTU::mbErrCode writeOutputSingleRegister( uniset::ModbusRTU::WriteSingleOutputMessage& query,
uniset::ModbusRTU::WriteSingleOutputRetMessage& reply );
/*! обработка запросов на чтение ошибок */
uniset::ModbusRTU::mbErrCode journalCommand( uniset::ModbusRTU::JournalCommandMessage& query,
uniset::ModbusRTU::JournalCommandRetMessage& reply );
/*! обработка запроса на установку времени */
uniset::ModbusRTU::mbErrCode setDateTime( uniset::ModbusRTU::SetDateTimeMessage& query,
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
/*! обработка запроса удалённого сервиса */
uniset::ModbusRTU::mbErrCode remoteService( uniset::ModbusRTU::RemoteServiceMessage& query,
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
uniset::ModbusRTU::mbErrCode fileTransfer( uniset::ModbusRTU::FileTransferMessage& query,
uniset::ModbusRTU::FileTransferRetMessage& reply );
uniset::ModbusRTU::mbErrCode diagnostics( uniset::ModbusRTU::DiagnosticMessage& query,
uniset::ModbusRTU::DiagnosticRetMessage& reply );
uniset::ModbusRTU::mbErrCode read4314( uniset::ModbusRTU::MEIMessageRDI& query,
uniset::ModbusRTU::MEIMessageRetRDI& reply );
/*! интерфейс ModbusRTUSlave для обмена по RS */
uniset::ModbusRTUSlaveSlot* rscomm;
std::unordered_set<uniset::ModbusRTU::ModbusAddr> vaddr; /*!< адреса на которые отвечаем */
bool verbose;
public:
MBSlave( const std::unordered_set<uniset::ModbusRTU::ModbusAddr>& vaddr, const std::string& dev, const std::string& speed, bool use485 = false );
~MBSlave();
inline void setVerbose( bool state )
{
verbose = state;
}
inline void setReply( long val )
{
replyVal = val;
}
inline void setReply2( long val )
{
replyVal2 = val;
}
inline void setReply3( long val )
{
replyVal3 = val;
}
void execute(); /*!< основной цикл работы */
void setLog( std::shared_ptr<DebugStream> dlog );
protected:
// действия при завершении работы
void sigterm( int signo );
/*! обработка 0x01 */
uniset::ModbusRTU::mbErrCode readCoilStatus( uniset::ModbusRTU::ReadCoilMessage& query,
uniset::ModbusRTU::ReadCoilRetMessage& reply );
/*! обработка 0x02 */
uniset::ModbusRTU::mbErrCode readInputStatus( uniset::ModbusRTU::ReadInputStatusMessage& query,
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
/*! обработка 0x03 */
uniset::ModbusRTU::mbErrCode readOutputRegisters( uniset::ModbusRTU::ReadOutputMessage& query,
uniset::ModbusRTU::ReadOutputRetMessage& reply );
/*! обработка 0x04 */
uniset::ModbusRTU::mbErrCode readInputRegisters( uniset::ModbusRTU::ReadInputMessage& query,
uniset::ModbusRTU::ReadInputRetMessage& reply );
/*! обработка 0x05 */
uniset::ModbusRTU::mbErrCode forceSingleCoil( uniset::ModbusRTU::ForceSingleCoilMessage& query,
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
/*! обработка 0x0F */
uniset::ModbusRTU::mbErrCode forceMultipleCoils( uniset::ModbusRTU::ForceCoilsMessage& query,
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
/*! обработка 0x10 */
uniset::ModbusRTU::mbErrCode writeOutputRegisters( uniset::ModbusRTU::WriteOutputMessage& query,
uniset::ModbusRTU::WriteOutputRetMessage& reply );
/*! обработка 0x06 */
uniset::ModbusRTU::mbErrCode writeOutputSingleRegister( uniset::ModbusRTU::WriteSingleOutputMessage& query,
uniset::ModbusRTU::WriteSingleOutputRetMessage& reply );
/*! обработка запросов на чтение ошибок */
uniset::ModbusRTU::mbErrCode journalCommand( uniset::ModbusRTU::JournalCommandMessage& query,
uniset::ModbusRTU::JournalCommandRetMessage& reply );
/*! обработка запроса на установку времени */
uniset::ModbusRTU::mbErrCode setDateTime( uniset::ModbusRTU::SetDateTimeMessage& query,
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
/*! обработка запроса удалённого сервиса */
uniset::ModbusRTU::mbErrCode remoteService( uniset::ModbusRTU::RemoteServiceMessage& query,
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
uniset::ModbusRTU::mbErrCode fileTransfer( uniset::ModbusRTU::FileTransferMessage& query,
uniset::ModbusRTU::FileTransferRetMessage& reply );
uniset::ModbusRTU::mbErrCode diagnostics( uniset::ModbusRTU::DiagnosticMessage& query,
uniset::ModbusRTU::DiagnosticRetMessage& reply );
uniset::ModbusRTU::mbErrCode read4314( uniset::ModbusRTU::MEIMessageRDI& query,
uniset::ModbusRTU::MEIMessageRetRDI& reply );
/*! интерфейс ModbusRTUSlave для обмена по RS */
uniset::ModbusRTUSlaveSlot* rscomm;
std::unordered_set<uniset::ModbusRTU::ModbusAddr> vaddr; /*!< адреса на которые отвечаем */
bool verbose;
#if 0
typedef std::unordered_map<uniset::ModbusRTU::mbErrCode, unsigned int> ExchangeErrorMap;
ExchangeErrorMap errmap; /*!< статистика обмена */
uniset::ModbusRTU::mbErrCode prev;
typedef std::unordered_map<uniset::ModbusRTU::mbErrCode, unsigned int> ExchangeErrorMap;
ExchangeErrorMap errmap; /*!< статистика обмена */
uniset::ModbusRTU::mbErrCode prev;
// можно было бы сделать unsigned, но аналоговые датчики у нас имеют
// тип long. А это число передаётся в графику в виде аналогового датчика
long askCount; /*!< количество принятых запросов */
// можно было бы сделать unsigned, но аналоговые датчики у нас имеют
// тип long. А это число передаётся в графику в виде аналогового датчика
long askCount; /*!< количество принятых запросов */
typedef std::unordered_map<int, std::string> FileList;
FileList flist;
typedef std::unordered_map<int, std::string> FileList;
FileList flist;
#endif
long replyVal;
long replyVal2;
long replyVal3;
private:
long replyVal;
long replyVal2;
long replyVal3;
private:
};
// -------------------------------------------------------------------------
......
......@@ -9,111 +9,111 @@
/*! Ничего не делающая реализация MBTCPServer для тестирования */
class MBTCPServer
{
public:
MBTCPServer( const std::unordered_set<uniset::ModbusRTU::ModbusAddr>& myaddr, const std::string& inetaddr, int port = 502, bool verbose = false );
~MBTCPServer();
public:
MBTCPServer( const std::unordered_set<uniset::ModbusRTU::ModbusAddr>& myaddr, const std::string& inetaddr, int port = 502, bool verbose = false );
~MBTCPServer();
inline void setVerbose( bool state )
{
verbose = state;
}
inline void setVerbose( bool state )
{
verbose = state;
}
inline void setReply( long val )
{
replyVal = val;
}
inline void setReply( long val )
{
replyVal = val;
}
inline uniset::timeout_t setAfterSendPause( uniset::timeout_t msec )
{
return sslot->setAfterSendPause(msec);
}
inline uniset::timeout_t setAfterSendPause( uniset::timeout_t msec )
{
return sslot->setAfterSendPause(msec);
}
void execute(); /*!< основной цикл работы */
void setLog( std::shared_ptr<DebugStream>& dlog );
void execute(); /*!< основной цикл работы */
void setLog( std::shared_ptr<DebugStream>& dlog );
void setMaxSessions( size_t max );
void setMaxSessions( size_t max );
protected:
// действия при завершении работы
void sigterm( int signo );
protected:
// действия при завершении работы
void sigterm( int signo );
/*! обработка 0x01 */
uniset::ModbusRTU::mbErrCode readCoilStatus( uniset::ModbusRTU::ReadCoilMessage& query,
uniset::ModbusRTU::ReadCoilRetMessage& reply );
/*! обработка 0x02 */
uniset::ModbusRTU::mbErrCode readInputStatus( uniset::ModbusRTU::ReadInputStatusMessage& query,
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
/*! обработка 0x01 */
uniset::ModbusRTU::mbErrCode readCoilStatus( uniset::ModbusRTU::ReadCoilMessage& query,
uniset::ModbusRTU::ReadCoilRetMessage& reply );
/*! обработка 0x02 */
uniset::ModbusRTU::mbErrCode readInputStatus( uniset::ModbusRTU::ReadInputStatusMessage& query,
uniset::ModbusRTU::ReadInputStatusRetMessage& reply );
/*! обработка 0x03 */
uniset::ModbusRTU::mbErrCode readOutputRegisters( uniset::ModbusRTU::ReadOutputMessage& query,
uniset::ModbusRTU::ReadOutputRetMessage& reply );
/*! обработка 0x03 */
uniset::ModbusRTU::mbErrCode readOutputRegisters( uniset::ModbusRTU::ReadOutputMessage& query,
uniset::ModbusRTU::ReadOutputRetMessage& reply );
/*! обработка 0x04 */
uniset::ModbusRTU::mbErrCode readInputRegisters( uniset::ModbusRTU::ReadInputMessage& query,
uniset::ModbusRTU::ReadInputRetMessage& reply );
/*! обработка 0x04 */
uniset::ModbusRTU::mbErrCode readInputRegisters( uniset::ModbusRTU::ReadInputMessage& query,
uniset::ModbusRTU::ReadInputRetMessage& reply );
/*! обработка 0x05 */
uniset::ModbusRTU::mbErrCode forceSingleCoil( uniset::ModbusRTU::ForceSingleCoilMessage& query,
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
/*! обработка 0x05 */
uniset::ModbusRTU::mbErrCode forceSingleCoil( uniset::ModbusRTU::ForceSingleCoilMessage& query,
uniset::ModbusRTU::ForceSingleCoilRetMessage& reply );
/*! обработка 0x0F */
uniset::ModbusRTU::mbErrCode forceMultipleCoils( uniset::ModbusRTU::ForceCoilsMessage& query,
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
/*! обработка 0x0F */
uniset::ModbusRTU::mbErrCode forceMultipleCoils( uniset::ModbusRTU::ForceCoilsMessage& query,
uniset::ModbusRTU::ForceCoilsRetMessage& reply );
/*! обработка 0x10 */
uniset::ModbusRTU::mbErrCode writeOutputRegisters( uniset::ModbusRTU::WriteOutputMessage& query,
uniset::ModbusRTU::WriteOutputRetMessage& reply );
/*! обработка 0x10 */
uniset::ModbusRTU::mbErrCode writeOutputRegisters( uniset::ModbusRTU::WriteOutputMessage& query,
uniset::ModbusRTU::WriteOutputRetMessage& reply );
/*! обработка 0x06 */
uniset::ModbusRTU::mbErrCode writeOutputSingleRegister( uniset::ModbusRTU::WriteSingleOutputMessage& query,
uniset::ModbusRTU::WriteSingleOutputRetMessage& reply );
/*! обработка 0x06 */
uniset::ModbusRTU::mbErrCode writeOutputSingleRegister( uniset::ModbusRTU::WriteSingleOutputMessage& query,
uniset::ModbusRTU::WriteSingleOutputRetMessage& reply );
uniset::ModbusRTU::mbErrCode diagnostics( uniset::ModbusRTU::DiagnosticMessage& query,
uniset::ModbusRTU::DiagnosticRetMessage& reply );
uniset::ModbusRTU::mbErrCode diagnostics( uniset::ModbusRTU::DiagnosticMessage& query,
uniset::ModbusRTU::DiagnosticRetMessage& reply );
uniset::ModbusRTU::mbErrCode read4314( uniset::ModbusRTU::MEIMessageRDI& query,
uniset::ModbusRTU::MEIMessageRetRDI& reply );
uniset::ModbusRTU::mbErrCode read4314( uniset::ModbusRTU::MEIMessageRDI& query,
uniset::ModbusRTU::MEIMessageRetRDI& reply );
/*! обработка запросов на чтение ошибок */
uniset::ModbusRTU::mbErrCode journalCommand( uniset::ModbusRTU::JournalCommandMessage& query,
uniset::ModbusRTU::JournalCommandRetMessage& reply );
/*! обработка запросов на чтение ошибок */
uniset::ModbusRTU::mbErrCode journalCommand( uniset::ModbusRTU::JournalCommandMessage& query,
uniset::ModbusRTU::JournalCommandRetMessage& reply );
/*! обработка запроса на установку времени */
uniset::ModbusRTU::mbErrCode setDateTime( uniset::ModbusRTU::SetDateTimeMessage& query,
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
/*! обработка запроса на установку времени */
uniset::ModbusRTU::mbErrCode setDateTime( uniset::ModbusRTU::SetDateTimeMessage& query,
uniset::ModbusRTU::SetDateTimeRetMessage& reply );
/*! обработка запроса удалённого сервиса */
uniset::ModbusRTU::mbErrCode remoteService( uniset::ModbusRTU::RemoteServiceMessage& query,
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
/*! обработка запроса удалённого сервиса */
uniset::ModbusRTU::mbErrCode remoteService( uniset::ModbusRTU::RemoteServiceMessage& query,
uniset::ModbusRTU::RemoteServiceRetMessage& reply );
uniset::ModbusRTU::mbErrCode fileTransfer( uniset::ModbusRTU::FileTransferMessage& query,
uniset::ModbusRTU::FileTransferRetMessage& reply );
uniset::ModbusRTU::mbErrCode fileTransfer( uniset::ModbusRTU::FileTransferMessage& query,
uniset::ModbusRTU::FileTransferRetMessage& reply );
/*! интерфейс ModbusSlave для обмена по RS */
uniset::ModbusTCPServerSlot* sslot;
std::unordered_set<uniset::ModbusRTU::ModbusAddr> vaddr; /*!< адреса данного узла */
/*! интерфейс ModbusSlave для обмена по RS */
uniset::ModbusTCPServerSlot* sslot;
std::unordered_set<uniset::ModbusRTU::ModbusAddr> vaddr; /*!< адреса данного узла */
bool verbose = { false };
long replyVal = { -1 };
bool verbose = { false };
long replyVal = { -1 };
#if 0
typedef std::unordered_map<uniset::ModbusRTU::mbErrCode, unsigned int> ExchangeErrorMap;
ExchangeErrorMap errmap; /*!< статистика обмена */
uniset::ModbusRTU::mbErrCode prev;
typedef std::unordered_map<uniset::ModbusRTU::mbErrCode, unsigned int> ExchangeErrorMap;
ExchangeErrorMap errmap; /*!< статистика обмена */
uniset::ModbusRTU::mbErrCode prev;
// можно было бы сделать unsigned, но аналоговые датчики у нас имеют
// тип long. А это число передаётся в графику в виде аналогового датчика
long askCount; /*!< количество принятых запросов */
// можно было бы сделать unsigned, но аналоговые датчики у нас имеют
// тип long. А это число передаётся в графику в виде аналогового датчика
long askCount; /*!< количество принятых запросов */
typedef std::unordered_map<int, std::string> FileList;
FileList flist;
typedef std::unordered_map<int, std::string> FileList;
FileList flist;
#endif
private:
private:
};
// -------------------------------------------------------------------------
......
......@@ -10,147 +10,147 @@ using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] =
{
{ "help", no_argument, 0, 'h' },
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "myaddr", required_argument, 0, 'a' },
{ "speed", required_argument, 0, 's' },
{ "use485F", no_argument, 0, 'y' },
{ "const-reply", required_argument, 0, 'c' },
{ NULL, 0, 0, 0 }
{ "help", no_argument, 0, 'h' },
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "myaddr", required_argument, 0, 'a' },
{ "speed", required_argument, 0, 's' },
{ "use485F", no_argument, 0, 'y' },
{ "const-reply", required_argument, 0, 'c' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h|--help - this message\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-a|--myaddr] addr - Modbus address for master. Default: 0x01.\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-c|--const-reply] val1 [val2 val3] - Reply val for all queries\n");
printf("-h|--help - this message\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-a|--myaddr] addr - Modbus address for master. Default: 0x01.\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-c|--const-reply] val1 [val2 val3] - Reply val for all queries\n");
}
// --------------------------------------------------------------------------
static char* checkArg( int ind, int argc, char* argv[] );
// --------------------------------------------------------------------------
int main( int argc, char** argv )
{
// std::ios::sync_with_stdio(false);
int optindex = 0;
int opt = 0;
int verb = 0;
string dev("/dev/ttyS0");
string speed("38400");
ModbusRTU::ModbusAddr myaddr = 0x01;
auto dlog = make_shared<DebugStream>();
int use485 = 0;
int replyVal = -1;
int replyVal2 = -1;
int replyVal3 = -1;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hva:d:s:yc:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'd':
dev = string(optarg);
break;
case 's':
speed = string(optarg);
break;
case 'a':
myaddr = ModbusRTU::str2mbAddr(optarg);
break;
case 'v':
verb = 1;
break;
case 'y':
use485 = 1;
break;
case 'c':
replyVal = uni_atoi(optarg);
if( checkArg(optind, argc, argv) )
replyVal2 = uni_atoi(argv[optind]);
if( checkArg(optind + 1, argc, argv) )
replyVal3 = uni_atoi(argv[optind + 1]);
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
{
cout << "(init): dev=" << dev << " speed=" << speed
<< " myaddr=" << ModbusRTU::addr2str(myaddr)
<< endl;
dlog->addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
}
/*! \todo Доделать возможность задавать много адресов для ответа */
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
vaddr.emplace(myaddr);
MBSlave mbs(vaddr, dev, speed, use485);
mbs.setLog(dlog);
mbs.setVerbose(verb);
if( replyVal != -1 )
mbs.setReply(replyVal);
if( replyVal2 != -1 )
mbs.setReply2(replyVal2);
if( replyVal3 != -1 )
mbs.setReply3(replyVal3);
mbs.execute();
}
catch( ModbusRTU::mbException& ex )
{
cerr << "(mbtester): " << ex << endl;
}
catch( const std::exception& ex )
{
cerr << "(mbslave): " << ex.what() << endl;
}
catch(...)
{
cerr << "(mbslave): catch(...)" << endl;
}
return 0;
// std::ios::sync_with_stdio(false);
int optindex = 0;
int opt = 0;
int verb = 0;
string dev("/dev/ttyS0");
string speed("38400");
ModbusRTU::ModbusAddr myaddr = 0x01;
auto dlog = make_shared<DebugStream>();
int use485 = 0;
int replyVal = -1;
int replyVal2 = -1;
int replyVal3 = -1;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hva:d:s:yc:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'd':
dev = string(optarg);
break;
case 's':
speed = string(optarg);
break;
case 'a':
myaddr = ModbusRTU::str2mbAddr(optarg);
break;
case 'v':
verb = 1;
break;
case 'y':
use485 = 1;
break;
case 'c':
replyVal = uni_atoi(optarg);
if( checkArg(optind, argc, argv) )
replyVal2 = uni_atoi(argv[optind]);
if( checkArg(optind + 1, argc, argv) )
replyVal3 = uni_atoi(argv[optind + 1]);
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
{
cout << "(init): dev=" << dev << " speed=" << speed
<< " myaddr=" << ModbusRTU::addr2str(myaddr)
<< endl;
dlog->addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
}
/*! \todo Доделать возможность задавать много адресов для ответа */
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
vaddr.emplace(myaddr);
MBSlave mbs(vaddr, dev, speed, use485);
mbs.setLog(dlog);
mbs.setVerbose(verb);
if( replyVal != -1 )
mbs.setReply(replyVal);
if( replyVal2 != -1 )
mbs.setReply2(replyVal2);
if( replyVal3 != -1 )
mbs.setReply3(replyVal3);
mbs.execute();
}
catch( ModbusRTU::mbException& ex )
{
cerr << "(mbtester): " << ex << endl;
}
catch( const std::exception& ex )
{
cerr << "(mbslave): " << ex.what() << endl;
}
catch(...)
{
cerr << "(mbslave): catch(...)" << endl;
}
return 0;
}
// --------------------------------------------------------------------------
char* checkArg( int i, int argc, char* argv[] )
{
if( i < argc && (argv[i])[0] != '-' )
return argv[i];
if( i < argc && (argv[i])[0] != '-' )
return argv[i];
return 0;
return 0;
}
// --------------------------------------------------------------------------
......@@ -10,150 +10,150 @@ using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] =
{
{ "help", no_argument, 0, 'h' },
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "myaddr", required_argument, 0, 'a' },
{ "speed", required_argument, 0, 's' },
{ "f485", no_argument, 0, 'g' },
{ NULL, 0, 0, 0 }
{ "help", no_argument, 0, 'h' },
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "myaddr", required_argument, 0, 'a' },
{ "speed", required_argument, 0, 's' },
{ "f485", no_argument, 0, 'g' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h|--help - this message\n");
printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-a|--myaddr] addr1,addr2,... - Modbus address for this slave. Default: 0x01.\n");
printf(" myaddr=0 - Reply to all RTU-addresses (broadcast).\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-g|--f485] - Use 485 Fastwel\n");
printf("-h|--help - this message\n");
printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-a|--myaddr] addr1,addr2,... - Modbus address for this slave. Default: 0x01.\n");
printf(" myaddr=0 - Reply to all RTU-addresses (broadcast).\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-g|--f485] - Use 485 Fastwel\n");
}
// --------------------------------------------------------------------------
int main( int argc, char** argv )
{
// std::ios::sync_with_stdio(false);
int optindex = 0;
int opt = 0;
int verb = 0;
int f485 = 0;
string dev("/dev/ttyS0");
string speed("38400");
std::string myaddr("0x01");
int tout = 2000;
DebugStream dlog;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hva:d:s:c:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'd':
dev = string(optarg);
break;
case 's':
speed = string(optarg);
break;
case 't':
tout = uni_atoi(optarg);
break;
case 'a':
myaddr = string(optarg);
break;
case 'v':
verb = 1;
break;
case 'g':
f485 = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
auto avec = uniset::explode_str(myaddr, ',');
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
for( const auto& a : avec )
vaddr.emplace( ModbusRTU::str2mbAddr(a) );
if( verb )
{
cout << "(init): dev=" << dev << " speed=" << speed
<< " myaddr=" << ModbusServer::vaddr2str(vaddr)
<< " timeout=" << tout << " msec "
<< endl;
dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
}
if( f485 )
{
// std::ios::sync_with_stdio(false);
int optindex = 0;
int opt = 0;
int verb = 0;
int f485 = 0;
string dev("/dev/ttyS0");
string speed("38400");
std::string myaddr("0x01");
int tout = 2000;
DebugStream dlog;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hva:d:s:c:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'd':
dev = string(optarg);
break;
case 's':
speed = string(optarg);
break;
case 't':
tout = uni_atoi(optarg);
break;
case 'a':
myaddr = string(optarg);
break;
case 'v':
verb = 1;
break;
case 'g':
f485 = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
auto avec = uniset::explode_str(myaddr, ',');
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
for( const auto& a : avec )
vaddr.emplace( ModbusRTU::str2mbAddr(a) );
if( verb )
{
cout << "(init): dev=" << dev << " speed=" << speed
<< " myaddr=" << ModbusServer::vaddr2str(vaddr)
<< " timeout=" << tout << " msec "
<< endl;
dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
}
if( f485 )
{
#ifndef DISABLE_COMPORT_485F
ComPort485F* cp;
if( dev == "/dev/ttyS2" )
cp = new ComPort485F(dev, 5);
else if( dev == "/dev/ttyS3" )
cp = new ComPort485F(dev, 6);
else
{
cerr << "dev must be /dev/ttyS2 or /dev/tytS3" << endl;
return 1;
}
MBSlave mbs(cp, vaddr, speed);
mbs.setLog(dlog);
mbs.setVerbose(verb);
mbs.execute();
ComPort485F* cp;
if( dev == "/dev/ttyS2" )
cp = new ComPort485F(dev, 5);
else if( dev == "/dev/ttyS3" )
cp = new ComPort485F(dev, 6);
else
{
cerr << "dev must be /dev/ttyS2 or /dev/tytS3" << endl;
return 1;
}
MBSlave mbs(cp, vaddr, speed);
mbs.setLog(dlog);
mbs.setVerbose(verb);
mbs.execute();
#else
cerr << "DISABLE_COMPORT_485F" << endl;
return 1;
cerr << "DISABLE_COMPORT_485F" << endl;
return 1;
#endif // #ifndef DISABLE_COMPORT_485F
}
else
{
MBSlave mbs(vaddr, dev, speed);
mbs.setLog(dlog);
mbs.setVerbose(verb);
mbs.execute();
}
}
catch( const ModbusRTU::mbException& ex )
{
cerr << "(mbtester): " << ex << endl;
}
catch( const std::exception& ex )
{
cerr << "(mbslave): " << ex.what() << endl;
}
catch(...)
{
cerr << "(mbslave): catch(...)" << endl;
}
return 0;
}
else
{
MBSlave mbs(vaddr, dev, speed);
mbs.setLog(dlog);
mbs.setVerbose(verb);
mbs.execute();
}
}
catch( const ModbusRTU::mbException& ex )
{
cerr << "(mbtester): " << ex << endl;
}
catch( const std::exception& ex )
{
cerr << "(mbslave): " << ex.what() << endl;
}
catch(...)
{
cerr << "(mbslave): catch(...)" << endl;
}
return 0;
}
// --------------------------------------------------------------------------
......@@ -9,134 +9,134 @@ using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] =
{
{ "help", no_argument, 0, 'h' },
{ "iaddr", required_argument, 0, 'i' },
{ "verbose", no_argument, 0, 'v' },
{ "myaddr", required_argument, 0, 'a' },
{ "port", required_argument, 0, 'p' },
{ "const-reply", required_argument, 0, 'c' },
{ "after-send-pause", required_argument, 0, 's' },
{ "max-sessions", required_argument, 0, 'm' },
{ NULL, 0, 0, 0 }
{ "help", no_argument, 0, 'h' },
{ "iaddr", required_argument, 0, 'i' },
{ "verbose", no_argument, 0, 'v' },
{ "myaddr", required_argument, 0, 'a' },
{ "port", required_argument, 0, 'p' },
{ "const-reply", required_argument, 0, 'c' },
{ "after-send-pause", required_argument, 0, 's' },
{ "max-sessions", required_argument, 0, 'm' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("Example: uniset-mbtcpserver-echo -i localhost -p 2049 -v \n");
printf("-h|--help - this message\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-i|--iaddr] ip - Server listen ip. Default 127.0.0.1\n");
printf("[-a|--myaddr] addr1,addr2,... - Modbus address for master. Default: 0x01.\n");
printf(" myaddr=0 - Reply to all RTU-addresses (broadcast).\n");
printf("[-p|--port] port - Server port. Default: 502.\n");
printf("[-c|--const-reply] val - Reply 'val' for all queries\n");
printf("[-s|--after-send-pause] msec - Pause after send request. Default: 0\n");
printf("[-m|--max-sessions] num - Set the maximum number of sessions. Default: 10\n");
printf("Example: uniset-mbtcpserver-echo -i localhost -p 2049 -v \n");
printf("-h|--help - this message\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-i|--iaddr] ip - Server listen ip. Default 127.0.0.1\n");
printf("[-a|--myaddr] addr1,addr2,... - Modbus address for master. Default: 0x01.\n");
printf(" myaddr=0 - Reply to all RTU-addresses (broadcast).\n");
printf("[-p|--port] port - Server port. Default: 502.\n");
printf("[-c|--const-reply] val - Reply 'val' for all queries\n");
printf("[-s|--after-send-pause] msec - Pause after send request. Default: 0\n");
printf("[-m|--max-sessions] num - Set the maximum number of sessions. Default: 10\n");
}
// --------------------------------------------------------------------------
int main( int argc, char** argv )
{
// std::ios::sync_with_stdio(false);
int optindex = 0;
int opt = 0;
int verb = 0;
int port = 502;
string iaddr("127.0.0.1");
string myaddr("0x01");
auto dlog = make_shared<DebugStream>();
int replyVal = -1;
timeout_t afterpause = 0;
size_t maxSessions = 10;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hva:p:i:c:s:m:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'i':
iaddr = string(optarg);
break;
case 'p':
port = uni_atoi(optarg);
break;
case 'a':
myaddr = string(optarg);
break;
case 'v':
verb = 1;
break;
case 'c':
replyVal = uni_atoi(optarg);
break;
case 's':
afterpause = uni_atoi(optarg);
break;
case 'm':
maxSessions = uni_atoi(optarg);
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
auto avec = uniset::explode_str(myaddr, ',');
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
for( const auto& a : avec )
vaddr.emplace( ModbusRTU::str2mbAddr(a) );
if( verb )
{
cout << "(init): iaddr: " << iaddr << ":" << port
<< " myaddr=" << ModbusServer::vaddr2str(vaddr)
<< endl;
dlog->addLevel( Debug::ANY );
}
MBTCPServer mbs(vaddr, iaddr, port, verb);
mbs.setLog(dlog);
mbs.setVerbose(verb);
mbs.setAfterSendPause(afterpause);
mbs.setMaxSessions(maxSessions);
if( replyVal != -1 )
mbs.setReply(replyVal);
mbs.execute();
}
catch( const ModbusRTU::mbException& ex )
{
cerr << "(mbtcpserver): " << ex << endl;
}
catch( const std::exception& e )
{
cerr << "(mbtcpserver): " << e.what() << endl;
}
catch(...)
{
cerr << "(mbtcpserver): catch(...)" << endl;
}
return 0;
// std::ios::sync_with_stdio(false);
int optindex = 0;
int opt = 0;
int verb = 0;
int port = 502;
string iaddr("127.0.0.1");
string myaddr("0x01");
auto dlog = make_shared<DebugStream>();
int replyVal = -1;
timeout_t afterpause = 0;
size_t maxSessions = 10;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hva:p:i:c:s:m:", longopts, &optindex);
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'i':
iaddr = string(optarg);
break;
case 'p':
port = uni_atoi(optarg);
break;
case 'a':
myaddr = string(optarg);
break;
case 'v':
verb = 1;
break;
case 'c':
replyVal = uni_atoi(optarg);
break;
case 's':
afterpause = uni_atoi(optarg);
break;
case 'm':
maxSessions = uni_atoi(optarg);
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
auto avec = uniset::explode_str(myaddr, ',');
std::unordered_set<ModbusRTU::ModbusAddr> vaddr;
for( const auto& a : avec )
vaddr.emplace( ModbusRTU::str2mbAddr(a) );
if( verb )
{
cout << "(init): iaddr: " << iaddr << ":" << port
<< " myaddr=" << ModbusServer::vaddr2str(vaddr)
<< endl;
dlog->addLevel( Debug::ANY );
}
MBTCPServer mbs(vaddr, iaddr, port, verb);
mbs.setLog(dlog);
mbs.setVerbose(verb);
mbs.setAfterSendPause(afterpause);
mbs.setMaxSessions(maxSessions);
if( replyVal != -1 )
mbs.setReply(replyVal);
mbs.execute();
}
catch( const ModbusRTU::mbException& ex )
{
cerr << "(mbtcpserver): " << ex << endl;
}
catch( const std::exception& e )
{
cerr << "(mbtcpserver): " << e.what() << endl;
}
catch(...)
{
cerr << "(mbtcpserver): catch(...)" << endl;
}
return 0;
}
// --------------------------------------------------------------------------
......@@ -8,28 +8,28 @@ using namespace std;
// --------------------------------------------------------------------------------
NullController::NullController( ObjectId id, const string& ioconfile,
const std::string& s_filterField,
const std::string& s_filterValue,
const std::string& c_filterField,
const std::string& c_filterValue,
bool _dumpingToDB ):
IONotifyController(id),
dumpingToDB(_dumpingToDB)
const std::string& s_filterField,
const std::string& s_filterValue,
const std::string& c_filterField,
const std::string& c_filterValue,
bool _dumpingToDB ):
IONotifyController(id),
dumpingToDB(_dumpingToDB)
{
restorer = NULL;
restorer = NULL;
auto ioconf = make_shared<IOConfig_XML>(ioconfile, uniset_conf());
ioconf->setItemFilter(s_filterField, s_filterValue);
ioconf->setConsumerFilter(c_filterField, c_filterValue);
auto ioconf = make_shared<IOConfig_XML>(ioconfile, uniset_conf());
ioconf->setItemFilter(s_filterField, s_filterValue);
ioconf->setConsumerFilter(c_filterField, c_filterValue);
restorer = std::static_pointer_cast<IOConfig>(ioconf);
restorer = std::static_pointer_cast<IOConfig>(ioconf);
/*
// askd->setReadItem( sigc::mem_fun(this,&NullController::readSItem) );
askd->setNCReadItem( sigc::mem_fun(this,&NullController::readSItem) );
askd->setReadThresholdItem( sigc::mem_fun(this,&NullController::readTItem) );
askd->setReadConsumerItem( sigc::mem_fun(this,&NullController::readCItem) );
*/
/*
// askd->setReadItem( sigc::mem_fun(this,&NullController::readSItem) );
askd->setNCReadItem( sigc::mem_fun(this,&NullController::readSItem) );
askd->setReadThresholdItem( sigc::mem_fun(this,&NullController::readTItem) );
askd->setReadConsumerItem( sigc::mem_fun(this,&NullController::readCItem) );
*/
}
// --------------------------------------------------------------------------------
......@@ -39,8 +39,8 @@ NullController::~NullController()
// --------------------------------------------------------------------------------
void NullController::dumpToDB()
{
if( dumpingToDB )
IONotifyController::dumpToDB();
if( dumpingToDB )
IONotifyController::dumpToDB();
}
// --------------------------------------------------------------------------------
/*
......
......@@ -6,28 +6,28 @@
#include "IONotifyController.h"
// --------------------------------------------------------------------------
class NullController:
public uniset::IONotifyController
public uniset::IONotifyController
{
public:
NullController(uniset::ObjectId id, const std::string& ioconfile,
const std::string& s_filterField = "",
const std::string& s_filterValue = "",
const std::string& c_filterField = "",
const std::string& c_filterValue = "",
bool _dumpingToDB = false );
public:
NullController(uniset::ObjectId id, const std::string& ioconfile,
const std::string& s_filterField = "",
const std::string& s_filterValue = "",
const std::string& c_filterField = "",
const std::string& c_filterValue = "",
bool _dumpingToDB = false );
virtual ~NullController();
virtual ~NullController();
protected:
protected:
virtual void dumpToDB();
virtual void dumpToDB();
// bool readSItem( UniXML& xml, UniXML::iterator& it, xmlNode* sec, NCRestorer::SInfo& inf );
// bool readTItem( UniXML& xml, UniXML::iterator& it, xmlNode* sec);
// bool readCItem( UniXML& xml, UniXML::iterator& it, xmlNode* sec);
// bool readSItem( UniXML& xml, UniXML::iterator& it, xmlNode* sec, NCRestorer::SInfo& inf );
// bool readTItem( UniXML& xml, UniXML::iterator& it, xmlNode* sec);
// bool readCItem( UniXML& xml, UniXML::iterator& it, xmlNode* sec);
private:
bool dumpingToDB;
private:
bool dumpingToDB;
};
// --------------------------------------------------------------------------
......
......@@ -9,86 +9,86 @@ using namespace std;
// --------------------------------------------------------------------------
static void short_usage()
{
cout << "Usage: uniset-nullController"
<< "--confile configure.xml. По умолчанию: configure.xml." << endl
<< " --name ObjectId [--confile configure.xml] [--askfile filename] \n"
<< " --s-filter-field name - поле для фильтрования списка датчиков\n"
<< " --s-filter-value value - значение для поля фильтрования списка датчиков \n"
<< " --c-filter-field name - поле для фильтрования списка заказчиков по каждому датчику\n"
<< " --c-filter-value value - значение для поля фильтрования списка заказчиков по каждому датчику\n"
<< " --dbDumping [0,1] - создавать ли dump-файл \n";
cout << "Usage: uniset-nullController"
<< "--confile configure.xml. По умолчанию: configure.xml." << endl
<< " --name ObjectId [--confile configure.xml] [--askfile filename] \n"
<< " --s-filter-field name - поле для фильтрования списка датчиков\n"
<< " --s-filter-value value - значение для поля фильтрования списка датчиков \n"
<< " --c-filter-field name - поле для фильтрования списка заказчиков по каждому датчику\n"
<< " --c-filter-value value - значение для поля фильтрования списка заказчиков по каждому датчику\n"
<< " --dbDumping [0,1] - создавать ли dump-файл \n";
}
// --------------------------------------------------------------------------
int main(int argc, char** argv)
{
// std::ios::sync_with_stdio(false);
// std::ios::sync_with_stdio(false);
try
{
if( argc <= 1 )
{
cerr << "\nНе указаны необходимые параметры\n\n";
short_usage();
return 0;
}
try
{
if( argc <= 1 )
{
cerr << "\nНе указаны необходимые параметры\n\n";
short_usage();
return 0;
}
if( !strcmp(argv[1], "--help") )
{
short_usage();
return 0;
}
if( !strcmp(argv[1], "--help") )
{
short_usage();
return 0;
}
auto conf = uniset_init(argc, argv, "configure.xml");
auto conf = uniset_init(argc, argv, "configure.xml");
// определяем ID объекта
string name = conf->getArgParam("--name");
// определяем ID объекта
string name = conf->getArgParam("--name");
if( name.empty())
{
cerr << "(nullController): не задан ObjectId!!! (--name)\n";
return 0;
}
if( name.empty())
{
cerr << "(nullController): не задан ObjectId!!! (--name)\n";
return 0;
}
ObjectId ID = conf->oind->getIdByName(conf->getControllersSection() + "/" + name);
ObjectId ID = conf->oind->getIdByName(conf->getControllersSection() + "/" + name);
if( ID == uniset::DefaultObjectId )
{
cerr << "(nullController): идентификатор '" << name
<< "' не найден в конф. файле!"
<< " в секции " << conf->getControllersSection() << endl;
return 0;
}
if( ID == uniset::DefaultObjectId )
{
cerr << "(nullController): идентификатор '" << name
<< "' не найден в конф. файле!"
<< " в секции " << conf->getControllersSection() << endl;
return 0;
}
// определяем ask-файл
string askfile = conf->getArgParam("--askfile");
// определяем ask-файл
string askfile = conf->getArgParam("--askfile");
if( askfile.empty())
askfile = conf->getConfFileName();
if( askfile.empty())
askfile = conf->getConfFileName();
// определяем фильтр
string s_field = conf->getArgParam("--s-filter-field");
string s_fvalue = conf->getArgParam("--s-filter-value");
string c_field = conf->getArgParam("--c-filter-field");
string c_fvalue = conf->getArgParam("--c-filter-value");
// определяем фильтр
string s_field = conf->getArgParam("--s-filter-field");
string s_fvalue = conf->getArgParam("--s-filter-value");
string c_field = conf->getArgParam("--c-filter-field");
string c_fvalue = conf->getArgParam("--c-filter-value");
// надо ли писать изменения в БД
bool dbDumping = conf->getArgInt("--dbDumping");
// надо ли писать изменения в БД
bool dbDumping = conf->getArgInt("--dbDumping");
auto nc = make_shared<NullController>(ID, askfile, s_field, s_fvalue, c_field, c_fvalue, dbDumping);
auto act = UniSetActivator::Instance();
act->add(nc);
act->run(false);
return 0;
}
catch( const std::exception& ex )
{
cerr << "(nullController::main): " << ex.what() << endl;
}
catch(...)
{
cerr << "(nullController::main): catch ..." << endl;
}
auto nc = make_shared<NullController>(ID, askfile, s_field, s_fvalue, c_field, c_fvalue, dbDumping);
auto act = UniSetActivator::Instance();
act->add(nc);
act->run(false);
return 0;
}
catch( const std::exception& ex )
{
cerr << "(nullController::main): " << ex.what() << endl;
}
catch(...)
{
cerr << "(nullController::main): catch ..." << endl;
}
return 1;
return 1;
}
......@@ -9,57 +9,57 @@ using namespace std;
// -----------------------------------------------------------------------------
int main( int argc, const char** argv )
{
// std::ios::sync_with_stdio(false);
// std::ios::sync_with_stdio(false);
try
{
if( argc > 1 && ( !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h") ) )
{
cout << "Usage: uniset-smonit [ args ] --sid id1@node1,Sensor2@node2,id2,sensorname3,... " << endl
<< "Args: " << endl
<< " --confile confilename - Default: configure.xml" << endl
<< " --name XXX - name for smonit. Default: TestProc" << endl;
// << " --script scriptname \n"
return 0;
}
try
{
if( argc > 1 && ( !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h") ) )
{
cout << "Usage: uniset-smonit [ args ] --sid id1@node1,Sensor2@node2,id2,sensorname3,... " << endl
<< "Args: " << endl
<< " --confile confilename - Default: configure.xml" << endl
<< " --name XXX - name for smonit. Default: TestProc" << endl;
// << " --script scriptname \n"
return 0;
}
auto conf = uniset_init(argc, argv, "configure.xml");
auto conf = uniset_init(argc, argv, "configure.xml");
ObjectId ID(DefaultObjectId);
string name = conf->getArgParam("--name", "TestProc");
ObjectId ID(DefaultObjectId);
string name = conf->getArgParam("--name", "TestProc");
ID = conf->getObjectID(name);
ID = conf->getObjectID(name);
if( ID == uniset::DefaultObjectId )
{
cerr << "(main): идентификатор '" << name
<< "' не найден в конф. файле!"
<< " в секции " << conf->getObjectsSection() << endl;
return 0;
}
if( ID == uniset::DefaultObjectId )
{
cerr << "(main): идентификатор '" << name
<< "' не найден в конф. файле!"
<< " в секции " << conf->getObjectsSection() << endl;
return 0;
}
auto act = UniSetActivator::Instance();
auto smon = make_shared<SMonitor>(ID);
act->add(smon);
auto act = UniSetActivator::Instance();
auto smon = make_shared<SMonitor>(ID);
act->add(smon);
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
act->run(false);
return 0;
}
catch( const uniset::Exception& ex )
{
cout << "(main):" << ex << endl;
}
catch( const std::exception& ex )
{
cout << "(main): exception: " << ex.what() << endl;
}
catch(...)
{
cout << "(main): Unknown exception!!" << endl;
}
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
act->run(false);
return 0;
}
catch( const uniset::Exception& ex )
{
cout << "(main):" << ex << endl;
}
catch( const std::exception& ex )
{
cout << "(main): exception: " << ex.what() << endl;
}
catch(...)
{
cout << "(main): Unknown exception!!" << endl;
}
return 1;
return 1;
}
// ------------------------------------------------------------------------------------------
......@@ -8,49 +8,49 @@ using namespace std;
// --------------------------------------------------------------------------
static void short_usage()
{
cout << "Usage: uniset-sviewer-text [--fullname] [--polltime msec] [--confile uniset-confile]\n";
cout << "Usage: uniset-sviewer-text [--fullname] [--polltime msec] [--confile uniset-confile]\n";
}
// --------------------------------------------------------------------------
int main(int argc, const char** argv)
{
// std::ios::sync_with_stdio(false);
try
{
if( argc > 1 && !strcmp(argv[1], "--help") )
{
short_usage();
return 0;
}
auto conf = uniset_init(argc, argv, "configure.xml");
bool fullname = false;
if( findArgParam("--fullname", conf->getArgc(), conf->getArgv()) != -1 )
fullname = true;
SViewer sv(conf->getControllersSection(), !fullname);
timeout_t timeMS = conf->getArgInt("--polltime");
if( timeMS )
{
cout << "(main): просматриваем с периодом " << timeMS << "[мсек]" << endl;
sv.monitor(timeMS);
}
else
sv.view();
return 0;
}
catch( const std::exception& ex )
{
cerr << "(main): Поймали исключение " << ex.what() << endl;
}
catch(...)
{
cerr << "(main): Неизвестное исключение!!!!" << endl;
}
return 1;
// std::ios::sync_with_stdio(false);
try
{
if( argc > 1 && !strcmp(argv[1], "--help") )
{
short_usage();
return 0;
}
auto conf = uniset_init(argc, argv, "configure.xml");
bool fullname = false;
if( findArgParam("--fullname", conf->getArgc(), conf->getArgv()) != -1 )
fullname = true;
SViewer sv(conf->getControllersSection(), !fullname);
timeout_t timeMS = conf->getArgInt("--polltime");
if( timeMS )
{
cout << "(main): просматриваем с периодом " << timeMS << "[мсек]" << endl;
sv.monitor(timeMS);
}
else
sv.view();
return 0;
}
catch( const std::exception& ex )
{
cerr << "(main): Поймали исключение " << ex.what() << endl;
}
catch(...)
{
cerr << "(main): Неизвестное исключение!!!!" << endl;
}
return 1;
}
......@@ -11,100 +11,100 @@ using namespace std;
// -------------------------------------------------------------------------
static struct option longopts[] =
{
{ "help", no_argument, 0, 'h' },
{ "iaddr", required_argument, 0, 'i' },
{ "port", required_argument, 0, 'p' },
{ "verbose", no_argument, 0, 'v' },
{ NULL, 0, 0, 0 }
{ "help", no_argument, 0, 'h' },
{ "iaddr", required_argument, 0, 'i' },
{ "port", required_argument, 0, 'p' },
{ "verbose", no_argument, 0, 'v' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("-h - this message\n");
printf("-v - Print all messages to stdout\n");
printf("-i addr - LogServer ip or hostname. Default: localhost.\n");
printf("-p port - LogServer port. Default: 3333.\n");
printf("-h - this message\n");
printf("-v - Print all messages to stdout\n");
printf("-i addr - LogServer ip or hostname. Default: localhost.\n");
printf("-p port - LogServer port. Default: 3333.\n");
}
// --------------------------------------------------------------------------
int main( int argc, char* argv[], char* envp[] )
{
int optindex = 0;
int opt = 0;
int verb = 0;
string addr("localhost");
int port = 3333;
int optindex = 0;
int opt = 0;
int verb = 0;
string addr("localhost");
int port = 3333;
try
{
while(1)
{
opt = getopt_long(argc, argv, "hvi:p:", longopts, &optindex);
try
{
while(1)
{
opt = getopt_long(argc, argv, "hvi:p:", longopts, &optindex);
if( opt == -1 )
break;
if( opt == -1 )
break;
switch (opt)
{
case 'h':
print_help();
return 0;
switch (opt)
{
case 'h':
print_help();
return 0;
case 'i':
addr = string(optarg);
break;
case 'i':
addr = string(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'v':
verb = 1;
break;
case 'v':
verb = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
cout << "(init): listen " << addr << ":" << port << endl;
if( verb )
cout << "(init): listen " << addr << ":" << port << endl;
auto log = make_shared<DebugStream>();
LogServer ls(log);
auto log = make_shared<DebugStream>();
LogServer ls(log);
ls.async_run(addr, port);
ls.async_run(addr, port);
char buf[10000];
char buf[10000];
while( true )
{
ssize_t r = read(fileno(stdin), buf, sizeof(buf) - 1);
while( true )
{
ssize_t r = read(fileno(stdin), buf, sizeof(buf) - 1);
if( r > 0 )
{
buf[r] = '\0';
log->any() << buf;
}
}
}
catch( const SystemError& err )
{
cerr << "(log-stdin): " << err << endl;
return 1;
}
catch( const uniset::Exception& ex )
{
cerr << "(log-stdin): " << ex << endl;
return 1;
}
catch(...)
{
cerr << "(log-stdin): catch(...)" << endl;
return 1;
}
if( r > 0 )
{
buf[r] = '\0';
log->any() << buf;
}
}
}
catch( const SystemError& err )
{
cerr << "(log-stdin): " << err << endl;
return 1;
}
catch( const uniset::Exception& ex )
{
cerr << "(log-stdin): " << ex << endl;
return 1;
}
catch(...)
{
cerr << "(log-stdin): catch(...)" << endl;
return 1;
}
return 0;
return 0;
}
// --------------------------------------------------------------------------
......@@ -16,106 +16,106 @@ using namespace std;
// -------------------------------------------------------------------------
static void print_help()
{
printf("\n");
printf("Usage: uniset2-logserver-wrap listen-addr listen-port PROGRAMM ARGS..\n");
printf("\n");
printf("\n");
printf("Usage: uniset2-logserver-wrap listen-addr listen-port PROGRAMM ARGS..\n");
printf("\n");
}
// --------------------------------------------------------------------------
int main( int argc, char* argv[], char* envp[] )
{
if( argc < 4 )
{
print_help();
return 1;
}
string addr(argv[1]);
int port = atoi(argv[2]);
int pid;
int cp[2]; /* Child to parent pipe */
if( pipe(cp) < 0)
{
perror("Can't make pipe");
exit(1);
}
try
{
switch( pid = fork() )
{
case -1:
{
perror("Can't fork");
exit(1);
}
case 0:
{
/* Child. */
close(cp[0]);
close( fileno(stdout) );
dup2(cp[1], fileno(stdout));
close( fileno(stderr) );
dup2(fileno(stdout), fileno(stderr));
execvpe(argv[3], argv + 3, envp);
perror("No exec");
kill(getppid(), SIGQUIT);
exit(1);
}
break;
default:
{
/* Parent. */
close(cp[1]);
auto zlog = make_shared<DebugStream>();
zlog->addLevel(Debug::ANY);
LogServer ls(zlog);
cout << "wrap: server " << addr << ":" << port << endl;
ls.async_run( addr, port );
char buf[5000];
while( true )
{
ssize_t r = read(cp[0], &buf, sizeof(buf) - 1 );
if( r > 0 )
{
buf[r] = '\0';
zlog->any() << buf;
}
}
exit(0);
}
break;
}
}
catch( const SystemError& err )
{
cerr << "(logserver-wrap): " << err << endl;
return 1;
}
catch( const uniset::Exception& ex )
{
cerr << "(logserver-wrap): " << ex << endl;
return 1;
}
catch(...)
{
cerr << "(logserver-wrap): catch(...)" << endl;
return 1;
}
return 0;
if( argc < 4 )
{
print_help();
return 1;
}
string addr(argv[1]);
int port = atoi(argv[2]);
int pid;
int cp[2]; /* Child to parent pipe */
if( pipe(cp) < 0)
{
perror("Can't make pipe");
exit(1);
}
try
{
switch( pid = fork() )
{
case -1:
{
perror("Can't fork");
exit(1);
}
case 0:
{
/* Child. */
close(cp[0]);
close( fileno(stdout) );
dup2(cp[1], fileno(stdout));
close( fileno(stderr) );
dup2(fileno(stdout), fileno(stderr));
execvpe(argv[3], argv + 3, envp);
perror("No exec");
kill(getppid(), SIGQUIT);
exit(1);
}
break;
default:
{
/* Parent. */
close(cp[1]);
auto zlog = make_shared<DebugStream>();
zlog->addLevel(Debug::ANY);
LogServer ls(zlog);
cout << "wrap: server " << addr << ":" << port << endl;
ls.async_run( addr, port );
char buf[5000];
while( true )
{
ssize_t r = read(cp[0], &buf, sizeof(buf) - 1 );
if( r > 0 )
{
buf[r] = '\0';
zlog->any() << buf;
}
}
exit(0);
}
break;
}
}
catch( const SystemError& err )
{
cerr << "(logserver-wrap): " << err << endl;
return 1;
}
catch( const uniset::Exception& ex )
{
cerr << "(logserver-wrap): " << ex << endl;
return 1;
}
catch(...)
{
cerr << "(logserver-wrap): catch(...)" << endl;
return 1;
}
return 0;
}
// --------------------------------------------------------------------------
......@@ -7,16 +7,16 @@ using namespace std;
// --------------------------------------------------------------------------
int main( int argc, char** argv )
{
if( argc < 2 || (argc > 1 && ( !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) ) // -V560
{
cout << "Usage: lo2gval [ info,warn,crit,level1...level9,init,repository,system,exception | any ]" << endl;
return 0;
}
if( argc < 2 || (argc > 1 && ( !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) ) // -V560
{
cout << "Usage: lo2gval [ info,warn,crit,level1...level9,init,repository,system,exception | any ]" << endl;
return 0;
}
const string s(argv[1]);
const string s(argv[1]);
cout << (int)Debug::value(s) << endl;
cout << (int)Debug::value(s) << endl;
return 0;
return 0;
}
// --------------------------------------------------------------------------
......@@ -287,6 +287,8 @@
virtual void httpGetUserData( Poco::JSON::Object::Ptr&amp; jdata ){} /*!&lt; для пользовательских данных в httpGet() */
virtual Poco::JSON::Object::Ptr httpDumpIO();
virtual Poco::JSON::Object::Ptr httpRequestLog( const Poco::URI::QueryParameters&amp; p );
virtual Poco::JSON::Object::Ptr request_params_set( const std::string&amp; req, const Poco::URI::QueryParameters&amp; p ) override;
virtual Poco::JSON::Object::Ptr request_params_get( const std::string&amp; req, const Poco::URI::QueryParameters&amp; p ) override;
#endif
</xsl:if>
// Выполнение очередного шага программы
......@@ -737,6 +739,116 @@ Poco::JSON::Object::Ptr <xsl:value-of select="$CLASSNAME"/>_SK::httpRequestLog(
return jret;
}
// -----------------------------------------------------------------------------
Poco::JSON::Object::Ptr <xsl:value-of select="$CLASSNAME"/>_SK::request_params_set( const std::string&amp; req, const Poco::URI::QueryParameters&amp; params )
{
Poco::JSON::Object::Ptr jret = new Poco::JSON::Object();
Poco::JSON::Array::Ptr jupdated = uniset::json::make_child_array(jret, "updated");
for( const auto&amp; p: params )
{
if( p.first == "sleep_msec" )
{
int val = uni_atoi(p.second);
if( val &gt; 0 )
{
sleep_msec = uni_atoi(p.second);
jupdated->add(p.first);
}
continue;
}
if( p.first == "resetMsgTime" )
{
int val = uni_atoi(p.second);
if( val &gt; 0 )
{
resetMsgTime = uni_atoi(p.second);
jupdated->add(p.first);
}
continue;
}
if( p.first == "forceOut" )
{
int val = uni_atoi(p.second);
if( val &gt; 0 )
{
forceOut = uni_atoi(p.second);
jupdated->add(p.first);
}
continue;
}
<xsl:for-each select="//variables/item">
<xsl:if test="normalize-space(@const)=''">
if( p.first == "<xsl:value-of select="@name"/>" )
{
<xsl:if test="normalize-space(@type)='int'"><xsl:value-of select="@name"/> = uni_atoi(p.second);</xsl:if>
<xsl:if test="normalize-space(@type)='long'"><xsl:value-of select="@name"/> = uni_atoi(p.second);</xsl:if>
<xsl:if test="normalize-space(@type)='float'"><xsl:value-of select="@name"/> = atof(p.second.c_str());</xsl:if>
<xsl:if test="normalize-space(@type)='double'"><xsl:value-of select="@name"/> = atof(p.second.c_str());</xsl:if>
<xsl:if test="normalize-space(@type)='bool'"><xsl:value-of select="@name"/> = uni_atoi(p.second);</xsl:if>
<xsl:if test="normalize-space(@type)='str'"><xsl:value-of select="@name"/> = p.second;</xsl:if>
jupdated->add(p.first);
continue;
}
</xsl:if>
</xsl:for-each>
}
jret->set("Result", (jupdated->size() > 0 ? "OK" : "FAIL") );
return jret;
}
// -----------------------------------------------------------------------------
Poco::JSON::Object::Ptr <xsl:value-of select="$CLASSNAME"/>_SK::request_params_get( const std::string&amp; req, const Poco::URI::QueryParameters&amp; params )
{
Poco::JSON::Object::Ptr jret = new Poco::JSON::Object();
if( params.empty() )
{
jret->set("sleep_msec",sleep_msec);
jret->set("resetMsgTime",resetMsgTime);
jret->set("forceOut",forceOut);
<xsl:for-each select="//variables/item">
<xsl:if test="normalize-space(@const)=''">
jret->set("<xsl:value-of select="@name"/>", <xsl:value-of select="@name"/>);
</xsl:if>
</xsl:for-each>
return jret;
}
for( const auto&amp; p: params )
{
if( p.first == "sleep_msec" )
{
jret->set(p.first,sleep_msec);
continue;
}
if( p.first == "resetMsgTime" )
{
jret->set(p.first,resetMsgTime);
continue;
}
if( p.first == "forceOut" )
{
jret->set(p.first,forceOut);
continue;
}
<xsl:for-each select="//variables/item">
<xsl:if test="normalize-space(@const)=''">
if( p.first == "<xsl:value-of select="@name"/>" )
{
jret->set(p.first, <xsl:value-of select="@name"/>);
continue;
}
</xsl:if>
</xsl:for-each>
}
return jret;
}
#endif
</xsl:if>
// -----------------------------------------------------------------------------
......
......@@ -8,42 +8,42 @@ using namespace std;
// -----------------------------------------------------------------------------
int main( int argc, const char** argv )
{
try
{
auto conf = uniset_init(argc, argv);
try
{
auto conf = uniset_init(argc, argv);
xmlNode* cnode = conf->getNode("Skel");
xmlNode* cnode = conf->getNode("Skel");
if( cnode == NULL )
{
cerr << "(Skel): not found <Skel> in conffile" << endl;
return 1;
}
if( cnode == NULL )
{
cerr << "(Skel): not found <Skel> in conffile" << endl;
return 1;
}
auto o = make_shared<Skel>("Skel", cnode);
auto o = make_shared<Skel>("Skel", cnode);
auto act = UniSetActivator::Instance();
act->add(o);
auto act = UniSetActivator::Instance();
act->add(o);
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
ulogany << "\n\n\n";
ulogany << "(Skel::main): -------------- Skel START -------------------------\n\n";
dlogany << "\n\n\n";
dlogany << "(Skel::main): -------------- Skel START -------------------------\n\n";
act->run(false);
return 0;
}
catch( const std::exception& ex )
{
cerr << "(Skel::main): " << ex.what() << endl;
}
catch(...)
{
cerr << "(Skel::main): catch(...)" << endl;
}
ulogany << "\n\n\n";
ulogany << "(Skel::main): -------------- Skel START -------------------------\n\n";
dlogany << "\n\n\n";
dlogany << "(Skel::main): -------------- Skel START -------------------------\n\n";
act->run(false);
return 0;
}
catch( const std::exception& ex )
{
cerr << "(Skel::main): " << ex.what() << endl;
}
catch(...)
{
cerr << "(Skel::main): catch(...)" << endl;
}
return 1;
return 1;
}
// -----------------------------------------------------------------------------
......@@ -5,7 +5,7 @@ using namespace std;
using namespace uniset;
// -----------------------------------------------------------------------------
Skel::Skel( uniset::ObjectId id, xmlNode* confnode ):
Skel_SK( id, confnode )
Skel_SK( id, confnode )
{
}
// -----------------------------------------------------------------------------
......@@ -15,8 +15,8 @@ Skel::~Skel()
// -----------------------------------------------------------------------------
Skel::Skel()
{
cerr << "(Skel): init failed!!!!!!!!!!!!!!!" << endl;
throw Exception();
cerr << "(Skel): init failed!!!!!!!!!!!!!!!" << endl;
throw Exception();
}
// -----------------------------------------------------------------------------
void Skel::step()
......
......@@ -5,21 +5,21 @@
#include "Skel_SK.h"
// -----------------------------------------------------------------------------
class Skel:
public Skel_SK
public Skel_SK
{
public:
Skel( uniset::ObjectId id, xmlNode* confnode = uniset::uniset_conf()->getNode("Skel") );
virtual ~Skel();
public:
Skel( uniset::ObjectId id, xmlNode* confnode = uniset::uniset_conf()->getNode("Skel") );
virtual ~Skel();
protected:
Skel();
protected:
Skel();
virtual void step() override;
virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
virtual void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void askSensors( UniversalIO::UIOCommand cmd ) override;
virtual void step() override;
virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
virtual void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void askSensors( UniversalIO::UIOCommand cmd ) override;
private:
private:
};
// -----------------------------------------------------------------------------
#endif // Skel_H_
......
......@@ -2,11 +2,11 @@ noinst_PROGRAMS = test test2
#test2
test_LDADD = $(top_builddir)/lib/libUniSet2.la $(POCO_LIBS)
test_CXXFLAGS = -I$(top_builddir)/include $(POCO_CGLAGS)
test_CXXFLAGS = -I$(top_builddir)/include $(POCO_CGLAGS) -Wno-unused-function
test_SOURCES = TestGen_SK.cc TestGen.cc TestGen-main.cc
test2_LDADD = $(top_builddir)/lib/libUniSet2.la $(POCO_LIBS)
test2_CXXFLAGS = -I$(top_builddir)/include $(POCO_CGLAGS)
test2_CXXFLAGS = -I$(top_builddir)/include $(POCO_CGLAGS) -Wno-unused-function
test2_SOURCES = TestGenAlone_SK.cc TestGenAlone.cc TestGenAlone-main.cc
GENERATED=TestGen_SK.h TestGen_SK.cc TestGen-main.cc
......
......@@ -5,29 +5,29 @@ using namespace std;
using namespace uniset;
// -----------------------------------------------------------------------------
TestGen::TestGen( uniset::ObjectId id, xmlNode* confnode ):
TestGen_SK( id, confnode )
TestGen_SK( id, confnode )
{
vmonit(int_var);
vmonit(bool_var);
vmonit(int_var);
vmonit(bool_var);
const long* i = valptr(input2_s);
long* k = outptr(output1_c);
const long* i = valptr(input2_s);
long* k = outptr(output1_c);
if( !k )
cerr << "output1_c NOT FOUND!!!" << endl;
if( !k )
cerr << "output1_c NOT FOUND!!!" << endl;
ObjectId d = idval(in_input2_s);
ObjectId d2 = idval(&in_input2_s);
ObjectId d3 = idval(i);
ObjectId d4 = idval(&out_output1_c);
ObjectId d = idval(in_input2_s);
ObjectId d2 = idval(&in_input2_s);
ObjectId d3 = idval(i);
ObjectId d4 = idval(&out_output1_c);
if( !i )
cerr << "input2_s NOT FOUND!!!" << endl;
else
cerr << "input2_s=" << (*i) << " d=" << d << " d2=" << d2 << " d3=" << d3 << " input2_s=" << input2_s << endl;
if( !i )
cerr << "input2_s NOT FOUND!!!" << endl;
else
cerr << "input2_s=" << (*i) << " d=" << d << " d2=" << d2 << " d3=" << d3 << " input2_s=" << input2_s << endl;
vmonit(t_val);
vmonit(t_val);
}
// -----------------------------------------------------------------------------
TestGen::~TestGen()
......@@ -36,61 +36,62 @@ TestGen::~TestGen()
// -----------------------------------------------------------------------------
TestGen::TestGen()
{
cerr << ": init failed!!!!!!!!!!!!!!!" << endl;
throw Exception();
cerr << ": init failed!!!!!!!!!!!!!!!" << endl;
throw Exception();
}
// -----------------------------------------------------------------------------
void TestGen::step()
{
#if 0
cout << "strval: " << strval(input2_s) << endl;
cout << "str: " << str(input2_s) << endl;
cout << "===========" << endl;
cout << dumpIO() << endl;
cout << "strval: " << strval(input2_s) << endl;
cout << "str: " << str(input2_s) << endl;
cout << "===========" << endl;
cout << dumpIO() << endl;
myinfo << str(input2_s) << endl;
ulog()->info() << "ulog: " << str(input2_s) << endl;
myinfo << str(input2_s) << endl;
ulog()->info() << "ulog: " << str(input2_s) << endl;
int_var++;
bool_var ^= true;
cout << vmon << endl;
int_var++;
bool_var ^= true;
cout << vmon << endl;
#endif
// cout << vmon.pretty_str() << endl;
// cout << vmon.pretty_str() << endl;
}
// -----------------------------------------------------------------------------
void TestGen::sensorInfo( const SensorMessage* sm )
{
if( sm->id == input1_s )
out_output1_c = in_input1_s; // sm->state
if( sm->id == input1_s )
out_output1_c = in_input1_s; // sm->state
}
// -----------------------------------------------------------------------------
void TestGen::timerInfo( const TimerMessage* tm )
{
if( tm->id == 1 )
{
askTimer(1, 0);
askTimer(2, 3000);
}
else if( tm->id == 2 )
{
askTimer(1, 2000);
askTimer(2, 0);
}
if( tm->id == 1 )
{
askTimer(1, 0);
askTimer(2, 3000);
}
else if( tm->id == 2 )
{
askTimer(1, 2000);
askTimer(2, 0);
}
}
// -----------------------------------------------------------------------------
#ifndef DISABLE_REST_API
void TestGen::httpGetUserData( Poco::JSON::Object::Ptr& jdata )
{
jdata->set("myMode", "RUNNING");
jdata->set("myVar", 42);
jdata->set("myFloatVar", 42.42);
jdata->set("myMessage", "This is text fot test httpGetUserData");
jdata->set("myMode", "RUNNING");
jdata->set("myVar", 42);
jdata->set("myFloatVar", 42.42);
jdata->set("myMessage", "This is text fot test httpGetUserData");
}
// -----------------------------------------------------------------------------
#endif
// -----------------------------------------------------------------------------
void TestGen::sysCommand( const uniset::SystemMessage* sm )
{
if( sm->command == SystemMessage::StartUp )
askTimer(1, 2000);
if( sm->command == SystemMessage::StartUp )
askTimer(1, 2000);
}
// -----------------------------------------------------------------------------
......@@ -5,26 +5,26 @@
#include "TestGen_SK.h"
// -----------------------------------------------------------------------------
class TestGen:
public TestGen_SK
public TestGen_SK
{
public:
TestGen( uniset::ObjectId id, xmlNode* confnode = uniset::uniset_conf()->getNode("TestGen") );
virtual ~TestGen();
public:
TestGen( uniset::ObjectId id, xmlNode* confnode = uniset::uniset_conf()->getNode("TestGen") );
virtual ~TestGen();
protected:
TestGen();
protected:
TestGen();
virtual void step() override;
virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
virtual void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
virtual void step() override;
virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
virtual void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
#ifndef DISABLE_REST_API
virtual void httpGetUserData( Poco::JSON::Object::Ptr& jdata ) override;
virtual void httpGetUserData( Poco::JSON::Object::Ptr& jdata ) override;
#endif
private:
bool bool_var = { false };
int int_var = {0};
uniset::timeout_t t_val = { 0 };
private:
bool bool_var = { false };
int int_var = {0};
uniset::timeout_t t_val = { 0 };
};
// -----------------------------------------------------------------------------
#endif // TestGen_H_
......
......@@ -5,7 +5,7 @@ using namespace std;
using namespace uniset;
// -----------------------------------------------------------------------------
TestGenAlone::TestGenAlone( uniset::ObjectId id, xmlNode* confnode ):
TestGenAlone_SK( id, confnode )
TestGenAlone_SK( id, confnode )
{
}
// -----------------------------------------------------------------------------
......@@ -15,13 +15,13 @@ TestGenAlone::~TestGenAlone()
// -----------------------------------------------------------------------------
void TestGenAlone::step()
{
cout << strval(in_input2_s) << endl;
cout << strval(in_input2_s) << endl;
}
// -----------------------------------------------------------------------------
void TestGenAlone::sensorInfo( const SensorMessage* sm )
{
if( sm->id == input1_s )
out_output1_c = in_input1_s; // sm->state
if( sm->id == input1_s )
out_output1_c = in_input1_s; // sm->state
}
// -----------------------------------------------------------------------------
void TestGenAlone::timerInfo( const TimerMessage* tm )
......
......@@ -5,19 +5,19 @@
#include "TestGenAlone_SK.h"
// -----------------------------------------------------------------------------
class TestGenAlone:
public TestGenAlone_SK
public TestGenAlone_SK
{
public:
TestGenAlone( uniset::ObjectId id, xmlNode* confnode = uniset::uniset_conf()->getNode("TestGenAlone") );
virtual ~TestGenAlone();
public:
TestGenAlone( uniset::ObjectId id, xmlNode* confnode = uniset::uniset_conf()->getNode("TestGenAlone") );
virtual ~TestGenAlone();
protected:
virtual void step() override;
void sensorInfo( const uniset::SensorMessage* sm ) override;
void timerInfo( const uniset::TimerMessage* tm ) override;
protected:
virtual void step() override;
void sensorInfo( const uniset::SensorMessage* sm ) override;
void timerInfo( const uniset::TimerMessage* tm ) override;
private:
private:
};
// -----------------------------------------------------------------------------
#endif // TestGenAlone_H_
......
......@@ -15,6 +15,7 @@
%def_enable api
%def_enable logdb
%def_enable opentsdb
%def_enable uresolver
%ifarch %ix86
%def_enable com485f
......@@ -25,11 +26,11 @@
%define oname uniset2
Name: libuniset2
Version: 2.9.0
Version: 2.9.1
Release: alt0.M90P.1
Summary: UniSet - library for building distributed industrial control systems
License: LGPL
License: LGPL-2.1
Group: Development/C++
Url: http://wiki.etersoft.ru/UniSet
......@@ -184,6 +185,14 @@ Obsoletes: %name-extentions-devel
%description extension-common-devel
Libraries needed to develop for uniset extensions
%if_enabled uresolver
%package extension-uresolver
Group: Development/Tools
Summary: CORBA object reference resolver based on http
%description extension-uresolver
CORBA object reference resolver based on http
%endif
%if_enabled mysql
%package extension-mysql
......@@ -523,6 +532,11 @@ rm -f %buildroot%_docdir/%oname/html/*.md5
%_includedir/%oname/extensions/mqtt/
%endif
%if_enabled uresolver
%files extension-uresolver
%_bindir/%oname-httpresolver*
%endif
%files extension-common-devel
%dir %_includedir/%oname/extensions
%_includedir/%oname/extensions/*.*
......@@ -546,14 +560,28 @@ rm -f %buildroot%_docdir/%oname/html/*.md5
# history of current unpublished changes
%changelog
* Sun Dec 13 2020 Pavel Vainerman <pv@altlinux.ru> 2.9.0-alt0.M90P.1
* Fri Jan 08 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.1-alt0.M90P.1
- backport to ALTLinux p9 (by rpmbph script)
* Sun Dec 13 2020 Pavel Vainerman <pv@altlinux.ru> 2.9.0-alt1
- (unet): message processing (zeop-copy optimization)
* Fri Jan 08 2021 Pavel Vainerman <pv@altlinux.ru> 2.9.1-alt1
- supported http-resolver (when localIOR=1)
* Thu Jan 07 2021 Pavel Vainerman <pv@altlinux.ru> 2.8.2-alt1
- supported "freeze vaule"
- modbus master: runtime reload config
- update docs
* Sat Jan 02 2021 Pavel Vainerman <pv@altlinux.ru> 2.8.1-alt3
- make style
- fixed docs
* Sun Dec 27 2020 Pavel Vainerman <pv@altlinux.ru> 2.8.1-alt2
- ALT spec: some fixes
* Sat Dec 05 2020 Pavel Vainerman <pv@altlinux.ru> 2.8.1-alt1
- (unet): unet recevier refactoring (optimization)
* Fri Dec 25 2020 Pavel Vainerman <pv@altlinux.ru> 2.8.1-alt1
- logserver/logreader refactoring
- update docs
- some python-module refactoring
* Sun Oct 25 2020 Pavel Vainerman <pv@altlinux.ru> 2.8-alt15
- minor fixes
......
......@@ -25,7 +25,9 @@
<BinDir name="./"/>
<LogDir name="./"/>
<DocDir name="./"/>
<LockDir name="./"/>
<LockDir name="/tmp/"/>
<HttpResolver name="HttpResolver"/>
<LocalIOR name="0"/>
<Services>
<LocalTimeService AskLifeTimeSEC="10" MaxCountTimers="100" name="TimeService"/>
<LocalInfoServer dbrepeat="1" name="InfoServer">
......
......@@ -3,10 +3,15 @@
# See doc: http://www.gnu.org/software/hello/manual/autoconf/Generic-Programs.html
# AC_PREREQ(2.59)
<<<<<<< HEAD
AC_INIT([uniset2], [2.8.1], pv@etersoft.ru)
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME,AC_PACKAGE_VERSION)
=======
AC_INIT([uniset2], [2.9.1], pv@etersoft.ru)
AM_INIT_AUTOMAKE
>>>>>>> 2.9.1-alt1
LIBVER=2:8:0
LIBVER=11:1:9
AC_SUBST(LIBVER)
# AC_CONFIG_MACRO_DIR([m4])
......@@ -32,9 +37,10 @@ AC_ENABLE_SHARED(yes)
AC_ENABLE_STATIC(no)
AM_PROG_LIBTOOL
ASTYLE_OPT="-A1 -T -C -S -N -L -w -Y -M -f -p --mode=c --lineend=linux --align-reference=type --align-pointer=type --suffix=none --style=ansi"
ASTYLE_OPT="-A1 -T -C -S -L -w -N -Y -M -f -p --mode=c --lineend=linux --align-reference=type --align-pointer=type --suffix=none --style=ansi --convert-tabs -s4"
AC_SUBST(ASTYLE_OPT)
# Checks for libraries.
PKG_CHECK_MODULES(XML, libxml-2.0)
PKG_CHECK_MODULES(OMNI, omniORB4)
......@@ -50,7 +56,7 @@ if test $checklibev = true; then
EV_CFLAGS=
AC_SUBST(EV_LIBS)
AC_SUBST(EV_CFLAGS)
AC_MSG_RESULT([ok])
AC_MSG_RESULT([ok])
fi
#check rest api support
......@@ -64,15 +70,16 @@ REST_API_CLIBS=
DISABLE_REST_API=
if test ${buildapi} = true; then
AC_MSG_RESULT([enabled])
AC_MSG_RESULT([enabled])
REST_API_CLIBS="-lPocoJSON"
else
AC_MSG_RESULT([disabled])
AC_MSG_RESULT([disabled])
REST_API_CFLAGS="-DDISABLE_REST_API"
DISABLE_REST_API=1
DISABLE_REST_API=1
fi
AM_CONDITIONAL(DISABLE_REST_API, test ${buildapi} = false)
AM_CONDITIONAL(ENABLE_REST_API, test ${buildapi} = true)
AC_SUBST(DISABLE_REST_API)
AC_SUBST(REST_API_CFLAGS)
AC_SUBST(REST_API_CLIBS)
......@@ -117,6 +124,7 @@ else
fi
AM_CONDITIONAL(DISABLE_SQLITE, test ${buildsqlite} = false)
AM_CONDITIONAL(ENABLE_SQLITE, test ${buildsqlite} = true)
# check xsltproc
AC_CHECK_PROG([XSLTPROC],[xsltproc],[yes])
......@@ -143,6 +151,8 @@ else
fi
AM_CONDITIONAL(DISABLE_MYSQL, test ${buildmysql} = false)
AM_CONDITIONAL(ENABLE_MYSQL, test ${buildmysql} = true)
#check pgsql support
AC_MSG_CHECKING([postgresql support])
......@@ -160,6 +170,7 @@ else
fi
AM_CONDITIONAL(DISABLE_PGSQL, test ${buildpgsql} = false)
AM_CONDITIONAL(ENABLE_PGSQL, test ${buildpgsql} = true)
#check rrd support
......@@ -178,6 +189,7 @@ else
fi
AM_CONDITIONAL(DISABLE_RRD, test ${buildrrd} = false)
AM_CONDITIONAL(ENABLE_RRD, test ${buildrrd} = true)
#check opentsdb support
AC_MSG_CHECKING([OpenTSDB backend])
......@@ -192,6 +204,7 @@ else
fi
AM_CONDITIONAL(DISABLE_OPENTSDB, test ${buildtsdb} = false)
AM_CONDITIONAL(ENABLE_OPENTSDB, test ${buildtsdb} = true)
#check io support
AC_MSG_CHECKING([io support])
......@@ -241,7 +254,7 @@ AC_SUBST(COMPORT_485F_CFLAGS)
#check logicproc build
AC_MSG_CHECKING([build logic processor extension])
buildlproc=true
AC_ARG_ENABLE(rrd, AC_HELP_STRING([--disable-logicproc], [disable build LogicProcessor extension]),
AC_ARG_ENABLE(logicproc, AC_HELP_STRING([--disable-logicproc], [disable build LogicProcessor extension]),
[ if test $enableval = yes; then buildlproc=true; else buildlproc=false; fi],[ buildlproc=true; ])
if test ${buildlproc} = true; then
AC_MSG_RESULT([enabled])
......@@ -250,6 +263,7 @@ else
fi
AM_CONDITIONAL(DISABLE_LOGICPROC, test ${buildlproc} = false)
AM_CONDITIONAL(ENABLE_LOGICPROC, test ${buildlproc} = true)
#check build extensions
ext=true
......@@ -297,6 +311,7 @@ else
fi
AM_CONDITIONAL(DISABLE_PYTHON, test ${buildpython} = false)
AM_CONDITIONAL(ENABLE_PYTHON, test ${buildpython} = true)
#check mqtt support
AC_MSG_CHECKING([mqtt support])
......@@ -316,6 +331,7 @@ else
fi
AM_CONDITIONAL(DISABLE_MQTT, test ${buildmqtt} = false)
AM_CONDITIONAL(ENABLE_MQTT, test ${buildmqtt} = true)
# check Doxygen
......@@ -388,6 +404,7 @@ else
fi
AM_CONDITIONAL(DISABLE_LOGDB, test ${buildlogdb} = false)
AM_CONDITIONAL(ENABLE_LOGDB, test ${buildlogdb} = true)
COV_LIBS=
COV_CFLAGS=
......@@ -579,6 +596,8 @@ AC_CONFIG_FILES([Makefile
extensions/tests/MQPerfTest/Makefile
extensions/LogDB/Makefile
extensions/LogDB/tests/Makefile
extensions/HttpResolver/Makefile
extensions/HttpResolver/tests/Makefile
testsuite/Makefile
wrappers/Makefile
wrappers/python/lib/Makefile
......
/*! \page ConfigurationPage Конфигурирование системы
- \ref ConfigurationPage_secCommon
- \ref ConfigurationPage_secOmniORB
- \ref ConfigurationPage_secCommon
- \ref ConfigurationPage_secOmniORB
- \ref ConfigurationPage_secOmniNames
- \ref ConfigurationPage_secLocalIOR
\section ConfigurationPage_secCommon Общее описание
\section ConfigurationPage_secCommon Общее описание
Для конфигурирования системы используется файл (обычно "configure.xml").
Конфигурация является глобальным объектом. Для получения доступа к ней используется функция auto conf = uniset_conf();
До начала работы, обычно в функции main(), конфигурация должна быть инициализирована при помощи функции uniset_init().
При этом третий параметр, указывающий название конфигурационного файла, является не обязательным.
По умолчанию обрабатывается аргумент командной строки --confile filename.
Для конфигурирования системы используется файл (обычно "configure.xml").
Конфигурация является глобальным объектом. Для получения доступа к ней используется функция auto conf = uniset_conf();
До начала работы, обычно в функции main(), конфигурация должна быть инициализирована при помощи функции uniset_init().
При этом третий параметр, указывающий название конфигурационного файла, является не обязательным.
По умолчанию обрабатывается аргумент командной строки --confile filename.
\code
...
#include <Configuration.h>
......@@ -20,41 +22,75 @@ int main(int argc, char **argv)
{
try
{
uniset_init(argc, argv, "configure.xml");
...
...
}
catch(Exception& ex )
uniset_init(argc, argv, "configure.xml");
...
...
}
catch(Exception& ex )
{
cerr << "(main): Поймали исключение " << ex << endl;
cerr << "(main): Поймали исключение " << ex << endl;
}
catch(...)
{
cerr << "Неизвестное исключение!!!!"<< endl;
cerr << "Неизвестное исключение!!!!"<< endl;
}
...
}
...
}
\endcode
\section ConfigurationPage_secOmniORB Конфигурирование OmniORB
Для возможности задать напрямую параметры для omniORB заложена специальная секция <omniORB>.
В данную секцию можно записывать любые параметры поддерживаемые библиотекой omniORB.
Формат и название параметров см. документацию по omniORB.
Пример:
\code
<omniORB>
<option name="endPoint" arg="giop:tcp:host1:"/>
<option name="endPoint" arg="giop:tcp:host2:" error_if_not_available="1"/>
</omniORB>
\endcode
\section ConfigurationPage_secOmniORB Конфигурирование OmniORB
Для возможности задать напрямую параметры для omniORB заложена специальная секция <omniORB>.
В данную секцию можно записывать любые параметры поддерживаемые библиотекой omniORB.
Формат и название параметров см. документацию по omniORB.
Пример:
Для параметра 'endPoint' встроена дополнительная проверка доступности указанного адреса.
\warning По умолчанию \b недоступность \b игнорируется, если не указан параметр \a error_if_not_available="1"
Помимо этого можно задать параметр \a ignore_checking="1", чтобы не происходило проверки доступности endPoint.
\section ConfigurationPage_secOmniNames Сервис имён
Сервис имён предназначен для получения ссылок на объекты (для возможности удалённого вызова)
по имени объекта. В данном проекте используется реализация службы имён входящая в состав
библиотеки omniORB. Сервис поставляется отдельной утилитой под названием omniNames, которая запускается отдельно.
В файле настроек проекта необходимо указать адрес сервиса
\code
<omniORB>
<option name="endPoint" arg="giop:tcp:host1:"/>
<option name="endPoint" arg="giop:tcp:host2:" error_if_not_available="1"/>
</omniORB>
<UniSet>
...
<NameService host="localhost" port="2809"/>
</UniSet>
\endcode
Для параметра 'endPoint' встроена дополнительная проверка доступности указанной адреса.
\warning По умолчанию \b недоступность \b игнорируется, если не указан параметр \a error_if_not_available="1"
Для большей надёжности рекомендуется запускать сервис имён на каждом узле отдельно, чтобы локальные объекты регистрировались в нём.
Но в общем случае сервис имён может быть запущен один на всю систему. Режим работы с использованием сервиса имён, позволяет
прозрачно обращаться к объектам где бы они не находились, на других узлах или локально.
Помимо этого можно задать параметр \a ignore_checking="1", чтобы не происходило проверки доступности endPoint.
\section ConfigurationPage_secLocalIOR Режим работы без сервиса имён
Режим работы без сервиса имён включается в настройках
\code
<UniSet>
...
<LocalIOR name="1"/>
<LockDir name="/var/lock/projectname/"/>
...
</<UniSet>
\endcode
или при запуске, при помощи аргумента командной строки `--localIOR 1`
*/
\ No newline at end of file
Данный режим предназначен для работы без использования сервиса имён (omniNames). При этом IOR-ссылки на объекты и датчики
публикуются локально в файлах, в каталоге `LockDir`. Такой режим значительно ускоряет запуск приложений, т.к. регистрация большого
количества датчиков в сервисе имён занимает много времени. Но по умолчанию в данном режиме работы недоступны удалённые вызовы на другие узлы. Т.е. например такой вызов работать не будет
\code
uniset2-admin --confile xxx --getValue sensor1@node2
\endcode
Для того чтобы удалённые вызовы были доступны, необходимо на каждом узле запустить специальный сервис HttpResolver
(см. \ref page_HttpResolver).
*/
/*! \page DebugPage Описание использования функций отладки
Класс для вывода отладочных сообщений называется DebugStream.
Сообщения могут выводится на экран и в файл, отбираться по
определённым критериям и до определённого уровня.
Класс для вывода отладочных сообщений называется DebugStream.
Сообщения могут выводится на экран и в файл, отбираться по
определённым критериям и до определённого уровня.
- \ref subUsing
- \ref subConf
- \ref subUsing
- \ref subConf
\subsection subUsing Использование
Для использования нужно создать свой объект класса DebugStream или
использовать глобальный объект UniSetTypes::unideb.
Для переключения вывода отладки в файл, используйте функцию logFile(char const *f);
Описание всех имеющихся функций находится в файле DebugStream.h
на английском языке.
\subsection subUsing Использование
Для использования нужно создать свой объект класса DebugStream или
использовать глобальный объект UniSetTypes::unideb.
Для переключения вывода отладки в файл, используйте функцию logFile(char const *f);
Функция unideb[...] по умолчанию выводит в строку дату и время.
Функция unideb(...) просто выводит строку (в конец предыдущему потоку).
\par Пример использования:
\code
#include "Debug.h"
#include "Configuration.h"
using namespace UniSetTypes;
...
unideb << "Этот текст будет выведен на экран в любом случае";
unideb.addLevel(Debug::CRIT); // показывать CRIT
unideb[Debug::CRIT] << "Этот текст будет выведен при разрешении выводить сообщения уровня CRIT";
unideb.delLevel(Debug::CRIT); // больше не показывать CRIT
// Отладочное сообщение будет выводиться при установленном уровне INFO или CRIT"
unideb[Debug::type(Debug::INFO | Debug::CRIT)] << "Отладочное сообщение";
Описание всех имеющихся функций находится в файле DebugStream.h
на английском языке.
// Вывод многострочного сообщения
unideb[Debug::INFO] << " вывод с датой и временем ";
unideb(Debug::INFO) << " продолжение вывода без даты и времени " << endl;
\endcode
Функция unideb[...] по умолчанию выводит в строку дату и время.
Функция unideb(...) просто выводит строку (в конец предыдущему потоку).
\par Пример использования:
\code
#include "Debug.h"
#include "Configuration.h"
using namespace UniSetTypes;
...
unideb << "Этот текст будет выведен на экран в любом случае";
unideb.addLevel(Debug::CRIT); // показывать CRIT
unideb[Debug::CRIT] << "Этот текст будет выведен при разрешении выводить сообщения уровня CRIT";
unideb.delLevel(Debug::CRIT); // больше не показывать CRIT
// Отладочное сообщение будет выводиться при установленном уровне INFO или CRIT"
unideb[Debug::type(Debug::INFO | Debug::CRIT)] << "Отладочное сообщение";
Если вы хотите использовать отладочный вывод из критичного к времени
кода, используйте следующую конструкцию:
\code
if (unideb.debugging(Debug::INFO)) {
unideb << "...debug output..." << endl;
}
\endcode
// Вывод многострочного сообщения
unideb[Debug::INFO] << " вывод с датой и временем ";
unideb(Debug::INFO) << " продолжение вывода без даты и времени " << endl;
\endcode
\subsection subConf Конфигурирование логов
Конфигурирование логов можно производить, при помощи файла конфигурации или через командную строку.
Например UniSetTypes::unideb настраивается в конфигурационном файле следующим образом:
Если вы хотите использовать отладочный вывод из критичного к времени
кода, используйте следующую конструкцию:
\code
<UniSetDebug name="unideb" levels="crit,warn" file=""/>
\endcode
При запуске программ используйте ключ "--help" для получения подробной информации
о настройке логов из командной строки
\code
if (unideb.debugging(Debug::INFO)) {
unideb << "...debug output..." << endl;
}
\endcode
\subsection subConf Конфигурирование логов
Конфигурирование логов можно производить, при помощи файла конфигурации или через командную строку.
Например UniSetTypes::unideb настраивается в конфигурационном файле следующим образом:
\code
<UniSetDebug name="unideb" levels="crit,warn" file=""/>
\endcode
При запуске программ используйте ключ "--help" для получения подробной информации
о настройке логов из командной строки
*/
\ No newline at end of file
/*!
\page MutexHowToPage Как пользоваться uniset_mutex и uniset_mutex_lock
\page MutexHowToPage Как пользоваться uniset_mutex и uniset_mutex_lock
\par
"мьютекс"(mutex) - получено от англ. Mutual Exclusive. (нечто вроде "взаимоисключение")
\par
Основными операциями для мьютексов, помимо создания и уничтожения, являются операции lock и unlock.
Логически работа с мьютексом могла бы выглядеть так (псевдокод)
\par
"мьютекс"(mutex) - получено от англ. Mutual Exclusive. (нечто вроде "взаимоисключение")
\par
Основными операциями для мьютексов, помимо создания и уничтожения, являются операции lock и unlock.
Логически работа с мьютексом могла бы выглядеть так (псевдокод)
\code
Mutex mutex;
...
mutex.lock();
DoSomething();
mutex.unlock();
\endcode
Но в общем случае это ни к чему хорошему не приведет, т.к. если в \c DoSomething() возникнет исключение, то
\c mutex.unlock() уже не выполнится. Конечно можно использовать \c try...catch, но желательно, чтобы
код работал независимо от ситуации. Для этого введен класс \b uniset_mutex_lock. При его использовании получается
следующий код (один из вариантов использования):
\code
using namespase UniSetTypes;
...
uniset_mutex mutex;
...
{
uniset_mutex_lock lock(mutex); // вызов mutex.lock() как часть кода конструктора
DoSomething();
} // <-- Заканчивается зона видимости lock-а и происходит вызов mutex.unlock() как часть кода деструктора
\endcode
В этом случае, даже если в \c DoSomethig() будет сгенерировано исключение ресурс будет освобожден
при вызове деструктора. Вот и все решение...
\par
Главное не забывайте ставить скобочки...
\par
Желательно не использовать \c mutex.lock() и \c uniset_mutex.unlock() в чистом виде, а только совместно с
\b uniset_mutex_lock. Кроме особых случаев (см. \ref secWarning).
\par
Следует помнить, что мьютексы \b фактически никаких ресурсов не захватывают, это только флаг означающий,
что ресурс занят. Поэтому работать с ними надо внимательно и не забывать блокировать ресурс там где это надо.
\par
Описания классов см. UniSetTypes::uniset_mutex и UniSetTypes::uniset_mutex_lock
\code
Mutex mutex;
...
mutex.lock();
DoSomething();
mutex.unlock();
\endcode
\section secWarning Особые случаи
Если в \c DoSomethig() будет вызвана \c exit(0), \c abort() или что-нибудь подобное,
то unlock не произойдет. В таком случае следовало бы напрямую вызывать \c unlock() до вызова сигнала, но эти случаи редкие и если
возникнет необходимость, то можно будет вместо \a protected сделать их \a public.
\note Описание составлено на основе описания мьютексов из книги А.Цимбала "Технология CORBA для профессионалов".
Но в общем случае это ни к чему хорошему не приведет, т.к. если в \c DoSomething() возникнет исключение, то
\c mutex.unlock() уже не выполнится. Конечно можно использовать \c try...catch, но желательно, чтобы
код работал независимо от ситуации. Для этого введен класс \b uniset_mutex_lock. При его использовании получается
следующий код (один из вариантов использования):
\code
using namespase UniSetTypes;
...
uniset_mutex mutex;
...
{
uniset_mutex_lock lock(mutex); // вызов mutex.lock() как часть кода конструктора
DoSomething();
} // <-- Заканчивается зона видимости lock-а и происходит вызов mutex.unlock() как часть кода деструктора
\endcode
В этом случае, даже если в \c DoSomethig() будет сгенерировано исключение ресурс будет освобожден
при вызове деструктора. Вот и все решение...
\par
Главное не забывайте ставить скобочки...
\par
Желательно не использовать \c mutex.lock() и \c uniset_mutex.unlock() в чистом виде, а только совместно с
\b uniset_mutex_lock. Кроме особых случаев (см. \ref secWarning).
\par
Следует помнить, что мьютексы \b фактически никаких ресурсов не захватывают, это только флаг означающий,
что ресурс занят. Поэтому работать с ними надо внимательно и не забывать блокировать ресурс там где это надо.
\par
Описания классов см. UniSetTypes::uniset_mutex и UniSetTypes::uniset_mutex_lock
\section secWarning Особые случаи
Если в \c DoSomethig() будет вызвана \c exit(0), \c abort() или что-нибудь подобное,
то unlock не произойдет. В таком случае следовало бы напрямую вызывать \c unlock() до вызова сигнала, но эти случаи редкие и если
возникнет необходимость, то можно будет вместо \a protected сделать их \a public.
\note Описание составлено на основе описания мьютексов из книги А.Цимбала "Технология CORBA для профессионалов".
*/
\ No newline at end of file
/* OBSOLETE DOC!!!
\page ObjectRepositoryPage Репозиторий объектов
\page ObjectRepositoryPage Репозиторий объектов
Репозиторий объектов предназначен для хранения и получения ссылок на объекты, с целью дальнейшего
использования функций предоставленных этими объектами. Объекты регистрирующиеся в репозитории могут быть удаленными...
Репозиторий объектов предназначен для хранения и получения ссылок на объекты, с целью дальнейшего
использования функций предоставленных этими объектами. Объекты регистрирующиеся в репозитории могут быть удаленными...
- \ref subRegCommon
- \ref subReg
- \ref subResolve
- \ref subRegCommon
- \ref subReg
- \ref subResolve
\section subRegCommon Вводная
При наследовании от UniSetObject (и его потомков) регистрация в репозитории происходит автоматически.
Поэтому регистрироваться отдельно нет необходимости.
\section subRegCommon Вводная
При наследовании от UniSetObject (и его потомков) регистрация в репозитории происходит автоматически.
Поэтому регистрироваться отдельно нет необходимости.
\section subReg Регистрация
Для регистрации существует следующие функции.
По текстовому имени
- void ObjectRepository::registration(const ObjectName name, const ObjectPtr oRef, const string section)
- void ObjectRepository::registration(const ObjectName fullName, const ObjectPtr oRef)
\section subReg Регистрация
Для регистрации существует следующие функции.
По текстовому имени
- void ObjectRepository::registration(const ObjectName name, const ObjectPtr oRef, const string section)
- void ObjectRepository::registration(const ObjectName fullName, const ObjectPtr oRef)
По идентификатору
- void UniversalInterface::registered(UniSetTypes::ObjectId id, const UniSetTypes::ObjectPtr oRef)throw(ORepFailed);
- void UniversalInterface::registered(UniSetTypes::ObjectId id, UniSetTypes::ObjectId node, const UniSetTypes::ObjectPtr oRef)throw(ORepFailed);
По идентификатору
- void UniversalInterface::registered(UniSetTypes::ObjectId id, const UniSetTypes::ObjectPtr oRef)throw(ORepFailed);
- void UniversalInterface::registered(UniSetTypes::ObjectId id, UniSetTypes::ObjectId node, const UniSetTypes::ObjectPtr oRef)throw(ORepFailed);
Пример:
\code
#include "ObjectRepository.h"
Пример:
\code
#include "ObjectRepository.h"
...
CORBA::Object_ptr oref;
...
ObjectRepository orep;
try
{
orep.registration("myObject", oref, "Root/Processes");
}
cacth(ORepFailed)
{
cerr << "Не удалось зарегистрировать объект " << endl;
}
\endcode
Или при помощи UniverslaInterface
\code
class MyObject:
public UniSetObject
{
public:
MyObject( UniSetTypes::ObjectId id );
...
protected:
void my_start()
{
try
{
ui.registration(myid, myRef);
}
catch(Exception ex)
{
cout << ex << endl;
}
}
}
\endcode
\section subResolve Получение ссылки на объект
...
CORBA::Object_ptr oref;
...
ObjectRepository orep;
try
{
orep.registration("myObject", oref, "Root/Processes");
}
cacth(ORepFailed)
{
cerr << "Не удалось зарегистрировать объект " << endl;
}
\endcode
Или при помощи UniverslaInterface
\code
class MyObject:
public UniSetObject
{
public:
MyObject( UniSetTypes::ObjectId id );
...
Для получения ссылки лучше всего пользоваться
- UniSetTypes::ObjectPtr UniversalInterface::resolve( UniSetTypes::ObjectId id )
- UniSetTypes::ObjectPtr UniversalInterface::resolve( UniSetTypes::ObjectId id, UniSetTypes::ObjectId nodeName, int timeoutMS=UniversalIO::defaultTimeOut)
throw(ResolveNameError, TimeOut);
protected:
void my_start()
{
try
{
ui.registration(myid, myRef);
}
catch(Exception ex)
{
cout << ex << endl;
}
}
}
\endcode
т.к. UniversalInterface::resolve() пытается получиться ссылку, в том числе через резервный каналы связи.
\section subResolve Получение ссылки на объект
Пример:
\code
...
try
{
CORBA::Object_ptr oref=0;
IOController_i_var ioc = IOController_i::_narrow( ui.resolve(id, node) );
...
}
catch(Exception ex)
{
cout << ex << endl;
}
Для получения ссылки лучше всего пользоваться
- UniSetTypes::ObjectPtr UniversalInterface::resolve( UniSetTypes::ObjectId id )
- UniSetTypes::ObjectPtr UniversalInterface::resolve( UniSetTypes::ObjectId id, UniSetTypes::ObjectId nodeName, int timeoutMS=UniversalIO::defaultTimeOut)
throw(ResolveNameError, TimeOut);
\endcode
т.к. UniversalInterface::resolve() пытается получиться ссылку, в том числе через резервный каналы связи.
Пример:
\code
...
try
{
CORBA::Object_ptr oref=0;
IOController_i_var ioc = IOController_i::_narrow( ui.resolve(id, node) );
...
}
catch(Exception ex)
{
cout << ex << endl;
}
\endcode
*/
\ No newline at end of file
......@@ -2,10 +2,29 @@
В библиотеке предусмотрен REST API. Есть два "уровня" доступа к REST API.
Первый - это встроенный в UniSetActivator http-сервер.
\ref sec_SM_REST_API
\sa \ref sec_SM_REST_API
\sa \ref sec_act_HttpAPI
Второй уровень. Это функция apiRequest(query) которую можно вызывать у каждого
объекта посредством RPC. Её вызов не требует наличия запущенного http-сервера.
объекта посредством RPC. Её вызов \b не \b требует наличия запущенного http-сервера.
Из консоли вызов можно делать при помощи утилиты uniset2-admin.
<br>Например так можно получить свойство "textname" для датчика ID=100
\code
uniset2-admin --apiRequest ObjectName "/api/v01/configure/get?100&props=textname"
\endcode
<br>А так можно посмотреть текущие параметры для объекта MyProcess
\code
uniset2-admin --apiRequest MyProcess "/api/v01/params/get"
\endcode
<br>Разные процессы могут расширять список базовых поддерживаемых команд.
Для того, чтобы узнать какие объект поддерживает команды, можно вызвать команду help
\code
uniset2-admin --apiRequest MyProcess "/api/v01/help"
\endcode
\warning С точки зрения надёжности функционирования системы наличие запущенного
http-сервера, а так же наличие функций \b getInfo(userparam) и \b apiRequest(query)
......@@ -13,4 +32,4 @@
реализации не контролируется. И при помощи больших запросов можно вызвать переполнение памяти
или крах процессов. На текущий момент контроль оставлен на разработчика конкретной реализации
getInfo() или apiRequest().
*/
\ No newline at end of file
*/
// эти разделы сформируются автоматически из описаний сделанных в соответствующих h-файлах
/*!
\page ServicesPage Сервисы
- \ref secDBServer
\section secDBServer Сервер БД
\sa \ref page_DBServer_MySQL
*/
\ No newline at end of file
/* OBSOLETE DOC!!!
\page UniversalInterfacePage Универсальный интерфейс
Этот интерфейс позволяет получать доступ к объекту по идентификатору(или имени), заказывать датчики, и т.п.
Для работы с удаленными объектами необходимо указывать идентификатор узла, на котором
находится этот объект(если он не задан, идет обращение к локальному).
- \ref secIOControl
- \ref subAsk
- \ref subGet
- \ref subSet
- \ref secTimers
- \ref secORep
\sa UniversalInterface
Этот интерфейс позволяет получать доступ к объекту по идентификатору(или имени), заказывать датчики, и т.п.
Для работы с удаленными объектами необходимо указывать идентификатор узла, на котором
находится этот объект(если он не задан, идет обращение к локальному).
- \ref secIOControl
- \ref subAsk
- \ref subGet
- \ref subSet
- \ref secTimers
- \ref secORep
\sa UniversalInterface
\section secIOControl Функции работы с вводом/выводом
\subsection subAsk Заказ датчиков
\subsection subAsk Заказ датчиков
Заказ датчиков осуществляется при помощи функций:
Заказ датчиков осуществляется при помощи функций:
для дискретных датчиков
- \ref void UniversalInterface::askState(...)
для дискретных датчиков
- \ref void UniversalInterface::askState(...)
для аналоговых датчиков
- \ref void UniversalInterface::askValue(...)
\subsection subGet Получение информации о текущем состоянии датчика
Информацию о состоянии датчика можно получить при помощи функций:
для аналоговых датчиков
- \ref void UniversalInterface::askValue(...)
\subsection subGet Получение информации о текущем состоянии датчика
Информацию о состоянии датчика можно получить при помощи функций:
для дискретных датчиков
- \ref void UniversalInterface::getState(...)
для дискретных датчиков
- \ref void UniversalInterface::getState(...)
для аналоговых датчиков
- \ref void UniversalInterface::getValue(...)
для аналоговых датчиков
- \ref void UniversalInterface::getValue(...)
\subsection subSet Управление выходными сигналом
\subsection subSet Управление выходными сигналом
для дискретных датчиков
- \ref void UniversalInterface::setState(...)
для дискретных датчиков
- \ref void UniversalInterface::setState(...)
для аналоговых датчиков
- \ref void UniversalInterface::setValue(...)
для аналоговых датчиков
- \ref void UniversalInterface::setValue(...)
\section secORep Функции работы с репозиторием объектов
- \ref void UniversalInterface::registered(...)
- \ref void UniversalInterface::unregister(...)
- \ref void UniversalInterface::resolve(...)
- \ref ObjectId UniversalInterface::getIdByName(...)
- \ref const char* UniversalInterface::getNameById(...)
- \ref void UniversalInterface::registered(...)
- \ref void UniversalInterface::unregister(...)
- \ref void UniversalInterface::resolve(...)
- \ref ObjectId UniversalInterface::getIdByName(...)
- \ref const char* UniversalInterface::getNameById(...)
\section secTimers Заказ таймеров
- \ref void UniversalInterface::askTimer(...)
- \ref void UniversalInterface::askTimer(...)
*/
/*!
\page DependsPage Зависимости между датчиками
Существует два механизма реализующих зависимость между датчиками:
Существует два механизма реализующих зависимость между датчиками:
- \ref pgDep_secIOControl
- \ref pgDep_secIOBase
\section pgDep_secIOControl Зависимость на уровне IOController (SharedMemmory)
\section pgDep_secIOControl Зависимость на уровне IOController (SharedMemmory)
Механизм зависимостей реализован в классе IOController.
Механизм зависимостей реализован в классе IOController.
Пример записи "зависимости" в configure.xml:
Пример записи "зависимости" в configure.xml:
\code
<item textname="...." iotype="..." .../>
<consumers>
<consumers>
<depends>
<depend name="Sensor1" filter="val" />
<depend name="Sensor2" filter2="val1" />
</depends>
</item>
<item textname="...." iotype="..." .../>
<consumers>
<consumers>
<depends>
<depend name="Sensor1" filter="val" />
<depend name="Sensor2" filter2="val1" />
</depends>
</item>
\endcode
При считывании конф. файла можно задавать фильтры.
ПОКА РЕАЛИЗОВАНА ЗАВИСИМОСТЬ ТОЛЬКО ОТ ОДНОГО ДАТЧИКА!
т.е. <depend> может быть только один.
\section pgDep_secIOBase Зависимость на уровне IOBase
Механизм зависимостей между датчиками на уровне IOBase,
При считывании конф. файла можно задавать фильтры.
ПОКА РЕАЛИЗОВАНА ЗАВИСИМОСТЬ ТОЛЬКО ОТ ОДНОГО ДАТЧИКА!
т.е. <depend> может быть только один.
\section pgDep_secIOBase Зависимость на уровне IOBase
Механизм зависимостей между датчиками на уровне IOBase,
работает на уровне процессов обмена использующих IOBase.
В ним относятся IOControl, ModbusMaster (RTU,TCP) и т.п.
Плюсом данного механизма является, то, что он обеспечивает
......@@ -42,9 +42,9 @@
Следует иметь ввиду, что этот механизм не действует при сохранении значений, например при помощи uniset-admin,
в отличие от механизма \ref pgDep_secIOControl
Пример записи "зависимости" в configure.xml:
Пример записи "зависимости" в configure.xml:
\code
<item textname="...." iotype="..." ... depend="OtherSensor_AS" depend_value="2" />
<item textname="...." iotype="..." ... depend="OtherSensor_AS" depend_value="2" />
\endcode
В данном случае подразумевается, что разрешающим датчиком является OtherSensor_AS=2.
......
# Заморозка (фиксация) значения датчика в SM
В библиотеке поддерживается механизм, позволяющий замораживать значение датчика и оно не будет меняться,
пока не будет обратно"разморожено". При этом функция `setValue()` будет продолжать работать и будет менять
значение датчика в памяти SM. Но пока датчик не будет разморожен эти изменения не будут видны.
После разморозки датчика, будет выставлено текущее значение.
Для управления "заморозкой" существует две возможности
### Заморозка значения при помощи утилиты uniset2-admin
Для того, чтобы заморозить какое-то значение достаточно вызвать команду
```
uniset2-admin --confile xxx --freezeValue SID@node=value 1
```
Где:
- `SID` - это имя или идентификатор датчика
- `node` - узел на котором датчик находится (необязательный параметр)
- `value` - значение которое будет установлено у датчика (при "разморозке" значение не важно)
- `1` - заморозить
Можно замораживать или размораживать сразу несколько датчиков.
- Заморозить датчики
```
uniset2-admin --confile xxx --freezeValue sens1=10,sens2=100,sens3=42 1
```
- Разморозить датчики
```
uniset2-admin --confile xxx --freezeValue sens1,sens2,sens3 0
```
### Заморозка значения при помощи UInterface (в коде)
Для "заморозки/разморозки" значений в коде в UInterface предусмотрена функция
```
void freezeValue( const IOController_i::SensorInfo& si, bool set, long value, uniset::ObjectId supplier );
```
Пример заморозки:
```
...
IOController_i::SensorInfo si;
si.id = 100; // sensorID
si.node = conf->getLocalNode();
ui->freezeValue(si, true, 100);
```
/*! \page page_Uniset Краткое описание библиотеки libuniset
- \ref pg_UniSet_Common
- \ref pg_Uniset_Processes
- \ref pg_UniSet_Network
- \ref pg_UniSet_Utilities
- \ref pg_UniSet_Common
- \ref pg_Uniset_Processes
- \ref pg_UniSet_Network
- \ref pg_UniSet_Utilities
\section pg_UniSet_Common Общее описание libuniset
......
/*!
\mainpage
\mainpage
\image html uniset.png
\image html uniset.png
\section MainSection Оглавление
\section MainSection Оглавление
- \ref page_Concept
- \ref page_Uniset
- \ref UniSetLibStylePage
*/
- \ref page_Concept
- \ref page_Uniset
*/
/*!
\page PythonPage Интерфейс на python
В проект входит два простых интерфейса для python:
- \ref pgPython_secUniSet
- \ref pgPython_secModbus
\section pgPython_secUniSet Простой python-интерфейс для работы с uniset
В данном интерфейсе реализован только самые просты функции \b getValue и \b setValue.
\sa UConnector
Пример использования:
\code
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from uniset import *
if __name__ == "__main__":
lst = Params_inst()
for i in range(0, len(sys.argv)):
if i >= Params.max:
break;
lst.add( sys.argv[i] )
p = []
print "lst: class: " + str(p.__class__.__name__)
try:
uc1 = UConnector( lst, "test.xml" )
# print "(0)UIType: %s" % uc1.getUIType()
print "(1)getShortName: id=%d name=%s" % (1, uc1.getShortName(1))
# print " getName: id=%d name=%s" % (1, uc1.getName(101))
# print " getTextName: id=%d name=%s" % (1, uc1.getTextName(101))
# print "\n"
# print "getShortName: id=%d name=%s" % (2, uc1.getShortName(109))
# print " getName: id=%d name=%s" % (2, uc1.getName(109))
# print " getTextName: id=%d name=%s" % (2, uc1.getTextName(109))
try:
print "(1)setValue: %d=%d" % (3,22)
uc1.setValue(3,22,DefaultID)
except UException, e:
print "(1)setValue exception: " + str(e.getError())
try:
print "(1)getValue: %d=%d" % ( 3, uc1.getValue(3,DefaultID) )
except UException, e:
print "(1)getValue exception: " + str(e.getError())
except UException, e:
print "(testUI): catch exception: " + str(e.getError())
\endcode
\section pgPython_secModbus Простой python-интерфейс для работы с modbus
В данном интерфейсе реализованы функции Modbus master на основе использования libuniset.
Он имеет ряд простых функций getWord(), getByte(), getBit(), а так же универсальная функция
UModbus::mbread() позволяющая более тонко определять параметры запроса.
Для записи одного регистра (!) реализована UModbus::mbwrite()
\sa UModbus
Пример использования:
\code
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from uniset import *
if __name__ == "__main__":
try:
mb = UModbus()
print "UIType: %s" % mb.getUIType()
mb.connect("localhost",2048)
try:
print "Test READ functions..."
for f in range(1,5):
print "func=%d reg=%d" % (f,22)
val = mb.mbread(0x01,22,f,"unsigned",-1)
# val = mb.mbread(0x01,22)
print "val=%d"%val
print "getWord: %d" % mb.getWord(0x01,22)
print "getByte: %d" % mb.getByte(0x01,22)
print "getBit: %d" % mb.getBit(0x01,22,3)
# print ""
# print "Test WRITE functions..."
# for f in range(1,6):
# print "func=%d reg=%d" % (f,22)
# val = mb.getValue(f,0x01,22,"unsigned",-1)
except UException, e:
print "exception: " + str(e.getError())
except UException, e:
print "(testUModbus): catch exception: " + str(e.getError())
\endcode
*/
# Интерфейс на python
В проект входит несколько python-интерфейсов
## Интерфейс для работы с uniset
В данном интерфейсе реализованы только самые просты функции \b getValue и \b setValue и некоторые вспомогательные,
позволяющие получать дополнительную информацию по датчикам.
\sa [UConnector](\ref UConnector)
Пример использования:
```
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from uniset import *
if __name__ == "__main__":
lst = Params_inst()
for i in range(0, len(sys.argv)):
if i >= Params.max:
break;
lst.add( sys.argv[i] )
try:
uc = UConnector( lst, "test.xml" )
print "(0)UIType: %s" % uc1.getUIType()
print "(1)getShortName: id=%d name=%s" % (1, uc.getShortName(1))
print " getName: id=%d name=%s" % (1, uc.getName(101))
print " getTextName: id=%d name=%s" % (1, uc.getTextName(101))
print "\n"
print "getShortName: id=%d name=%s" % (2, uc.getShortName(109))
print " getName: id=%d name=%s" % (2, uc.getName(109))
print " getTextName: id=%d name=%s" % (2, uc.getTextName(109))
try:
print "(1)setValue: %d=%d" % (3,22)
uc.setValue(3,22,DefaultID)
except UException, e:
print "(1)setValue exception: " + str(e.getError())
try:
print "(1)getValue: %d=%d" % ( 3, uc.getValue(3,DefaultID) )
except UException, e:
print "(1)getValue exception: " + str(e.getError())
except UException, e:
print "(testUI): catch exception: " + str(e.getError())
```
## Интерфейс для работы с modbus
В данном интерфейсе реализованы функции Modbus master на основе использования libuniset.
Он имеет ряд простых функций getWord(), getByte(), getBit(), а так же универсальная функция
UModbus::mbread(...) позволяющая более тонко определять параметры запроса.
Для записи одного регистра реализована UModbus::mbwrite()
\sa UModbus
Пример использования:
```
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from uniset import *
if __name__ == "__main__":
try:
mb = UModbus()
print "UIType: %s" % mb.getUIType()
mb.connect("localhost",2048)
try:
print "Test READ functions..."
for f in range(1,5):
print "func=%d reg=%d" % (f,22)
val = mb.mbread(0x01,22,f,"unsigned",-1)
# val = mb.mbread(0x01,22)
print "val=%d"%val
print "getWord: %d" % mb.getWord(0x01,22)
print "getByte: %d" % mb.getByte(0x01,22)
print "getBit: %d" % mb.getBit(0x01,22,3)
except UException, e:
print "exception: " + str(e.getError())
except UException, e:
print "(testUModbus): catch exception: " + str(e.getError())
```
## Работа c заказом датчиков
В данной реализации в фоне (в отдельном от питон системном потоке) создаётся proxy-объект,
который заказывает датчики и асинхронно в фоне получает уведомления об их изменении.
При этом из python-программы путём периодического опроса при помощи getValue() можно значения
забирать. Такой режим работы позволяет не делать каждый раз "удалённые вызовы" для получения
значений датчиков, обновление будет происходить асинхронно в фоновом потоке.
При этом после создания такого объекта, необходимо при помощи функции `addToAsk(id)` добавить
интересующие датчики, после чего для активации объекта необходимо вызвать функцию
`uniset_activate_objects()`
**warning:** функция `uniset_activate_objects()` должна быть вызвана только один раз в начале работы программы.
Пример:
```
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from uniset import *
if __name__ == "__main__":
# command line arguments
lst = Params_inst()
for i in range(0, len(sys.argv)):
if i >= Params.max:
break;
lst.add(sys.argv[i])
try:
uniset_init_params(lst, "test.xml");
# create proxxy-object
obj1 = UProxyObject("TestProc")
# ask sensors
obj1.addToAsk(1)
obj1.addToAsk(10)
# run proxy objects
uniset_activate_objects()
# work..
while True:
print "get current value..."
print "getValue: sensorID=%d value=%d" % (10, getValue(10))
time.sleep(2) # do some work
except UException, e:
print "(testUI): catch exception: " + str(e.getError())
```
/*!
\page ToDoPage Необходимо доделать
\page ToDoPage Необходимо доделать
-# утилиты мониторинга работы системы
-# настройку "политик" для ORB сделать из конф. файла
-# по максимуму переход на xml
-# дополнить описание IOController-ов разделом про XML-файл заказчиков(создание,работа)
-# сделать описание принципов и деталей межобъектного взаимодействия
(об ограничениях на размер сообщений, очередь сообщений, приоритеты и т.п.)
-# попытаться сделать работу с сервисами более универсальной
(что то типа "UniSetTypes::ObjectId conf->getService(const string name)" )
-# откорректировать и дописать "общее описание" библиотеки
-# сделать тип в UniSetObject::getType string-ом
(для универсальности и простоты будущих расширений)
-# переписать тестовые примеры, под текущую ситуацию.
-# в будущем попытаться отказаться от ObjectId и перейти на строки (это надо ещё обдумать)
-# в InfoServer-е по routeList-у сообщения пересылаются, только если они локальные.
Надо переделать механизм, чтобы можно было отделять тех кому пересылать все сообщения,
от тех кому пересылать только локальные....
-# Для IOController-ов разработать спец. интерфейс для работы с датчиками (сохранение, получение состояния и т.п.)
Для того, чтобы можно было использовать разные способы хранения (БД, STL-контейнеры, файлы и т.п.). Т.к. сейчас
жёсткая реализация на STL-контейнерах.
-# дописать Mutex как надо (или перейти на omni_mutex-ы) . Сделать RWMutex и RMutex.
-# стартовые скрипты для локальной отладки (откорректировать старые)
-# управление очередью сообщений, очистка по фильтру и т.п. (может перейти на несколько очередей по приоритетам)
-# У NotifyController-а две функции с название calibrate (надо переименовать)
-# Сделать свойство tick у процессов обмена по Modbus, чтобы можно было с разной периодичностью опрашивать разные регистры
-# утилиты мониторинга работы системы
-# настройку "политик" для ORB сделать из конф. файла
-# по максимуму переход на xml
-# дополнить описание IOController-ов разделом про XML-файл заказчиков(создание,работа)
-# сделать описание принципов и деталей межобъектного взаимодействия
(об ограничениях на размер сообщений, очередь сообщений, приоритеты и т.п.)
-# попытаться сделать работу с сервисами более универсальной
(что то типа "UniSetTypes::ObjectId conf->getService(const string name)" )
-# откорректировать и дописать "общее описание" библиотеки
-# сделать тип в UniSetObject::getType string-ом
(для универсальности и простоты будущих расширений)
-# переписать тестовые примеры, под текущую ситуацию.
-# в будущем попытаться отказаться от ObjectId и перейти на строки (это надо ещё обдумать)
-# в InfoServer-е по routeList-у сообщения пересылаются, только если они локальные.
Надо переделать механизм, чтобы можно было отделять тех кому пересылать все сообщения,
от тех кому пересылать только локальные....
-# Для IOController-ов разработать спец. интерфейс для работы с датчиками (сохранение, получение состояния и т.п.)
Для того, чтобы можно было использовать разные способы хранения (БД, STL-контейнеры, файлы и т.п.). Т.к. сейчас
жёсткая реализация на STL-контейнерах.
-# дописать Mutex как надо (или перейти на omni_mutex-ы) . Сделать RWMutex и RMutex.
-# стартовые скрипты для локальной отладки (откорректировать старые)
-# управление очередью сообщений, очистка по фильтру и т.п. (может перейти на несколько очередей по приоритетам)
-# У NotifyController-а две функции с название calibrate (надо переименовать)
-# Сделать свойство tick у процессов обмена по Modbus, чтобы можно было с разной периодичностью опрашивать разные регистры
*/
......@@ -817,7 +817,8 @@ FILE_PATTERNS = *.dox \
*.cc \
*.h \
*.idl \
*.py
*.py \
*.md
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
......@@ -2294,7 +2295,7 @@ CALLER_GRAPH = NO
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
GRAPHICAL_HIERARCHY = YES
GRAPHICAL_HIERARCHY = NO
# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
# dependencies a directory has on other directories in a graphical way. The
......
......@@ -817,7 +817,8 @@ FILE_PATTERNS = *.dox \
*.cc \
*.h \
*.idl \
*.py
*.py \
*.md
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
......
if DISABLE_OPENTSDB
else
if ENABLE_OPENTSDB
bin_PROGRAMS = @PACKAGE@-backend-opentsdb
TSDB_VER=@LIBVER@
......
......@@ -11,59 +11,59 @@ using namespace uniset::extensions;
// -----------------------------------------------------------------------------
int main( int argc, const char** argv )
{
// std::ios::sync_with_stdio(false);
// std::ios::sync_with_stdio(false);
if( argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) )
{
cout << "--smemory-id objectName - SharedMemory objectID. Default: autodetect" << endl;
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
cout << endl;
BackendOpenTSDB::help_print(argc, argv);
return 0;
}
if( argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) )
{
cout << "--smemory-id objectName - SharedMemory objectID. Default: autodetect" << endl;
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
cout << endl;
BackendOpenTSDB::help_print(argc, argv);
return 0;
}
try
{
auto conf = uniset_init( argc, argv );
try
{
auto conf = uniset_init( argc, argv );
ObjectId shmID = DefaultObjectId;
string sID = conf->getArgParam("--smemory-id");
ObjectId shmID = DefaultObjectId;
string sID = conf->getArgParam("--smemory-id");
if( !sID.empty() )
shmID = conf->getControllerID(sID);
else
shmID = getSharedMemoryID();
if( !sID.empty() )
shmID = conf->getControllerID(sID);
else
shmID = getSharedMemoryID();
if( shmID == DefaultObjectId )
{
cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
return 1;
}
if( shmID == DefaultObjectId )
{
cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
return 1;
}
auto db = BackendOpenTSDB::init_opendtsdb(argc, argv, shmID);
auto db = BackendOpenTSDB::init_opendtsdb(argc, argv, shmID);
if( !db )
{
cerr << "(opendtsdb): init failed..." << endl;
return 1;
}
if( !db )
{
cerr << "(opendtsdb): init failed..." << endl;
return 1;
}
auto act = UniSetActivator::Instance();
act->add(db);
auto act = UniSetActivator::Instance();
act->add(db);
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
act->run(false);
return 0;
}
catch( uniset::Exception& ex )
{
cerr << "(opendtsdb): " << ex << std::endl;
}
catch(...)
{
cerr << "(opendtsdb): catch ..." << std::endl;
}
SystemMessage sm(SystemMessage::StartUp);
act->broadcast( sm.transport_msg() );
act->run(false);
return 0;
}
catch( uniset::Exception& ex )
{
cerr << "(opendtsdb): " << ex << std::endl;
}
catch(...)
{
cerr << "(opendtsdb): catch ..." << std::endl;
}
return 1;
return 1;
}
if DISABLE_MYSQL
else
if ENABLE_MYSQL
UMYSQL_VER=@LIBVER@
lib_LTLIBRARIES = libUniSet2-mysql.la
......
......@@ -26,196 +26,196 @@ using namespace uniset;
// -----------------------------------------------------------------------------------------
MySQLInterface::MySQLInterface():
lastQ(""),
connected(false)
lastQ(""),
connected(false)
{
mysql = new MYSQL();
mysql_init(mysql);
// mysql_options(mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
mysql_options(mysql, MYSQL_OPT_COMPRESS, 0);
mysql = new MYSQL();
mysql_init(mysql);
// mysql_options(mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
mysql_options(mysql, MYSQL_OPT_COMPRESS, 0);
}
MySQLInterface::~MySQLInterface()
{
try
{
close();
}
catch( ... ) // пропускаем все необработанные исключения, если требуется обработать нужно вызывать close() до деструктора
{
cerr << "MySQLInterface::~MySQLInterface(): an error occured while closing connection!" << endl;
}
try
{
close();
}
catch( ... ) // пропускаем все необработанные исключения, если требуется обработать нужно вызывать close() до деструктора
{
cerr << "MySQLInterface::~MySQLInterface(): an error occured while closing connection!" << endl;
}
delete mysql;
delete mysql;
}
// -----------------------------------------------------------------------------------------
bool MySQLInterface::nconnect(const string& host, const string& user, const string& pswd, const string& dbname, unsigned int port )
{
if( !mysql_real_connect(mysql, host.c_str(), user.c_str(), pswd.c_str(), dbname.c_str(), port, NULL, 0) )
{
cout << error() << endl;
mysql_close(mysql);
connected = false;
return false;
}
if( !mysql_real_connect(mysql, host.c_str(), user.c_str(), pswd.c_str(), dbname.c_str(), port, NULL, 0) )
{
cout << error() << endl;
mysql_close(mysql);
connected = false;
return false;
}
connected = true;
return true;
connected = true;
return true;
}
// -----------------------------------------------------------------------------------------
bool MySQLInterface::close()
{
mysql_close(mysql);
return true;
mysql_close(mysql);
return true;
}
// -----------------------------------------------------------------------------------------
bool MySQLInterface::insert( const string& q )
{
if( !mysql )
return false;
if( !mysql )
return false;
if( mysql_query(mysql, q.c_str()) )
return false;
if( mysql_query(mysql, q.c_str()) )
return false;
return true;
return true;
}
// -----------------------------------------------------------------------------------------
DBResult MySQLInterface::query( const std::string& q )
{
if( !mysql )
return DBResult();
if( !mysql )
return DBResult();
if( mysql_query(mysql, q.c_str()) )
{
cerr << error() << endl;
return DBResult();
}
if( mysql_query(mysql, q.c_str()) )
{
cerr << error() << endl;
return DBResult();
}
lastQ = q;
MYSQL_RES* res = mysql_store_result(mysql); // _use_result - некорректно работает с _num_rows
lastQ = q;
MYSQL_RES* res = mysql_store_result(mysql); // _use_result - некорректно работает с _num_rows
if( !res || mysql_num_rows(res) == 0 )
return DBResult();
if( !res || mysql_num_rows(res) == 0 )
return DBResult();
return makeResult(res, true);
return makeResult(res, true);
}
// -----------------------------------------------------------------------------------------
bool MySQLInterface::query_ok( const string& q )
{
if( !mysql )
return false;
if( !mysql )
return false;
if( mysql_query(mysql, q.c_str()) )
return false;
if( mysql_query(mysql, q.c_str()) )
return false;
lastQ = q;
MYSQL_RES* res = mysql_store_result(mysql); // _use_result - некорректно работает с _num_rows
lastQ = q;
MYSQL_RES* res = mysql_store_result(mysql); // _use_result - некорректно работает с _num_rows
if( !res || mysql_num_rows(res) == 0 )
{
if( res )
mysql_free_result(res);
if( !res || mysql_num_rows(res) == 0 )
{
if( res )
mysql_free_result(res);
return false;
}
return false;
}
mysql_free_result(res);
return true;
mysql_free_result(res);
return true;
}
// -----------------------------------------------------------------------------------------
const string MySQLInterface::error()
{
return mysql_error(mysql);
return mysql_error(mysql);
}
// -----------------------------------------------------------------------------------------
const string MySQLInterface::lastQuery()
{
return lastQ;
return lastQ;
}
// -----------------------------------------------------------------------------------------
double MySQLInterface::insert_id()
{
if( !mysql )
return 0;
if( !mysql )
return 0;
return mysql_insert_id(mysql);
return mysql_insert_id(mysql);
}
// -----------------------------------------------------------------------------------------
const char* MySQLInterface::gethostinfo() const
{
return mysql_get_host_info(mysql);
return mysql_get_host_info(mysql);
}
// -----------------------------------------------------------------------------------------
bool MySQLInterface::ping() const
{
if( !mysql || !connected )
return false;
if( !mysql || !connected )
return false;
// внимание mysql_ping возвращает 0
// если всё хорошо.... (поэтому мы инвертируем)
return !mysql_ping(mysql);
// внимание mysql_ping возвращает 0
// если всё хорошо.... (поэтому мы инвертируем)
return !mysql_ping(mysql);
}
// -----------------------------------------------------------------------------------------
bool MySQLInterface::isConnection() const
{
return ping(); //!mysql;
return ping(); //!mysql;
}
// -----------------------------------------------------------------------------------------
string MySQLInterface::addslashes( const string& str )
{
ostringstream tmp;
ostringstream tmp;
for( unsigned int i = 0; i < str.size(); i++ )
{
// if( !strcmp(str[i],'\'') )
if( str[i] == '\'' )
tmp << "\\";
for( unsigned int i = 0; i < str.size(); i++ )
{
// if( !strcmp(str[i],'\'') )
if( str[i] == '\'' )
tmp << "\\";
tmp << str[i];
}
tmp << str[i];
}
return tmp.str();
return tmp.str();
}
// -----------------------------------------------------------------------------------------
DBResult MySQLInterface::makeResult( MYSQL_RES* myres, bool finalize )
{
DBResult result;
DBResult result;
if( !myres )
{
if( finalize )
mysql_free_result(myres);
if( !myres )
{
if( finalize )
mysql_free_result(myres);
return result;
}
return result;
}
MYSQL_ROW mysql_row;
unsigned int nfields = mysql_num_fields(myres);
MYSQL_ROW mysql_row;
unsigned int nfields = mysql_num_fields(myres);
while( (mysql_row = mysql_fetch_row(myres)) )
{
DBResult::COL c;
while( (mysql_row = mysql_fetch_row(myres)) )
{
DBResult::COL c;
for( unsigned int i = 0; i < nfields; i++ )
{
MYSQL_FIELD* field_info = mysql_fetch_field_direct(myres, i);
result.setColName( i, std::string(field_info->name) );
for( unsigned int i = 0; i < nfields; i++ )
{
MYSQL_FIELD* field_info = mysql_fetch_field_direct(myres, i);
result.setColName( i, std::string(field_info->name) );
c.emplace_back( (mysql_row[i] != 0 ? string(mysql_row[i]) : "") );
}
c.emplace_back( (mysql_row[i] != 0 ? string(mysql_row[i]) : "") );
}
result.row().emplace_back(c);
}
result.row().emplace_back(c);
}
if( finalize )
mysql_free_result(myres);
if( finalize )
mysql_free_result(myres);
return result;
return result;
}
// -----------------------------------------------------------------------------------------
extern "C" std::shared_ptr<DBInterface> create_mysqlinterface()
{
return std::shared_ptr<DBInterface>(new MySQLInterface(), DBInterfaceDeleter());
return std::shared_ptr<DBInterface>(new MySQLInterface(), DBInterfaceDeleter());
}
// -----------------------------------------------------------------------------------------
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment