[ref]同步
This commit is contained in:
parent
0777279524
commit
fbfa28fc2e
@ -18,7 +18,7 @@
|
||||
#include "CAcsCardMng.h"
|
||||
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
CAcsCardMng::CAcsCardMng(CAcsDeviceApiImpl *pParent)
|
||||
@ -237,4 +237,4 @@ void CAcsCardMng::onSetCardCfgFinish(bool bSuccess)
|
||||
}
|
||||
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -17,7 +17,7 @@ typedef unsigned long DWORD;
|
||||
typedef unsigned int DWORD;
|
||||
#endif
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
class CAcsDeviceApiImpl;
|
||||
@ -55,4 +55,4 @@ private:
|
||||
|
||||
};
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
#include "CAcsDeviceApiImplFactory.h"
|
||||
#include "app_bio_identify/acs_device_api/CAcsDeviceApi.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
CAcsDeviceApi::CAcsDeviceApi() :
|
||||
@ -114,4 +114,4 @@ bool CAcsDeviceApi::enableListenEvents(bool bEnable)
|
||||
return m_pImpl->enableListenEvents(bEnable);
|
||||
}
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
#include "app_bio_identify/acs_device_api/CAcsDeviceApi.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
CAcsDeviceApi::CAcsDeviceApi() :
|
||||
@ -74,4 +74,4 @@ bool CAcsDeviceApi::enableListenEvents(bool /*bEnable*/)
|
||||
return false;
|
||||
}
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
#include "app_bio_identify/acs_device_api/CAcsDeviceApi.h"
|
||||
#include "CAcsDeviceApiImpl.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
CAcsDeviceApiImpl::CAcsDeviceApiImpl(CAcsDeviceApi *pParent) :
|
||||
@ -199,14 +199,14 @@ bool CAcsDeviceApiImpl::setUserInfoToDevice(const std::list<CUserInfo> &listUser
|
||||
delete m_pListUserInfo;
|
||||
m_pListUserInfo = new std::list<CUserInfo>(listUserInfo);
|
||||
//< 先将结果全部设为false
|
||||
for (std::list<iot_application::CUserInfo>::iterator itUser = m_pListUserInfo->begin();
|
||||
for (std::list<iot_app::CUserInfo>::iterator itUser = m_pListUserInfo->begin();
|
||||
m_pListUserInfo->end() != itUser; ++itUser)
|
||||
{
|
||||
itUser->m_bSetCarSuccess = false;
|
||||
itUser->m_bSetFaceSuccess = false;
|
||||
|
||||
std::list<iot_application::CFingerprintInfo> &listFp = itUser->m_listFingerprint;
|
||||
for (std::list<iot_application::CFingerprintInfo>::iterator itFp = listFp.begin();
|
||||
std::list<iot_app::CFingerprintInfo> &listFp = itUser->m_listFingerprint;
|
||||
for (std::list<iot_app::CFingerprintInfo>::iterator itFp = listFp.begin();
|
||||
listFp.end() != itFp; ++itFp)
|
||||
{
|
||||
itFp->m_bSetSuccess = false;
|
||||
@ -463,4 +463,4 @@ bool CAcsDeviceApiImpl::enableListenEvents(bool bEnable)
|
||||
return true;
|
||||
}
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -20,7 +20,7 @@ typedef unsigned long DWORD;
|
||||
typedef unsigned int DWORD;
|
||||
#endif
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
class CAcsDeviceApi;
|
||||
@ -82,4 +82,4 @@ private:
|
||||
CAcsFingerprintMng m_objFpMng;
|
||||
};
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
#include "app_bio_identify/acs_device_api/CAcsDeviceApi.h"
|
||||
#include "CAcsDeviceApiImplFactory.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
#ifdef OS_WINDOWS
|
||||
@ -294,4 +294,4 @@ void CAcsDeviceApiImplFactory::destoryAcsDeviceApiImpl(CAcsDeviceApiImpl **ppObj
|
||||
releaseGlobal();
|
||||
}
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
#include "CAcsDeviceApiImpl.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
class CAcsDeviceApi;
|
||||
@ -49,4 +49,4 @@ private:
|
||||
static std::set<CAcsDeviceApiImpl *> m_setInstance;
|
||||
};
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
#include "CAcsFaceMng.h"
|
||||
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
CAcsFaceMng::CAcsFaceMng(CAcsDeviceApiImpl *pParent)
|
||||
@ -435,4 +435,4 @@ void CAcsFaceMng::onSetFaceCfgFinish(bool bSuccess)
|
||||
//< 无需再启动后续步骤
|
||||
}
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -17,7 +17,7 @@ typedef unsigned long DWORD;
|
||||
typedef unsigned int DWORD;
|
||||
#endif
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
class CAcsFaceMng
|
||||
@ -59,4 +59,4 @@ private:
|
||||
|
||||
};
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
#include "CAcsDeviceApiImpl.h"
|
||||
#include "CAcsFingerprintMng.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
CAcsFingerprintMng::CAcsFingerprintMng(CAcsDeviceApiImpl *pParent)
|
||||
@ -507,4 +507,4 @@ void CAcsFingerprintMng::onSetFpCfgFinish(bool bSuccess)
|
||||
}
|
||||
}
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -17,7 +17,7 @@ typedef unsigned long DWORD;
|
||||
typedef unsigned int DWORD;
|
||||
#endif
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
class CAcsDeviceApiImpl;
|
||||
@ -63,4 +63,4 @@ private:
|
||||
|
||||
};
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -18,7 +18,7 @@ HEADERS += $$PWD/../../../include/application/app_bio_identify/acs_device_api/Ac
|
||||
$$PWD/../../../include/application/app_bio_identify/acs_device_api/CAcsDeviceApi.h \
|
||||
|
||||
# 当前海康sdk只有X86版本
|
||||
contains(QMAKE_HOST.arch, x86_64){
|
||||
contains(QMAKE_HOST.arch, x86_64) : !linux-aarch64*{
|
||||
|
||||
HEADERS += CAcsDeviceApiImpl.h \
|
||||
CAcsDeviceApiImplFactory.h \
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#include "BisCommon.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -9,9 +9,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
#include "CAcsWorkThread.h"
|
||||
#include "CAcsDevice.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
CAcsDevice::CAcsDevice(CAcsWorkThread *pParent, const char *szTagName,
|
||||
@ -73,7 +73,7 @@ void CAcsDevice::handleFingerprintInfo(bool bSuccess, size_t nDataLen, const cha
|
||||
LOGERROR("handleFingerprintInfo(): 服务程序不应运行至此处,检查程序!");
|
||||
}
|
||||
|
||||
void CAcsDevice::handleSetUserInfoResult(const std::list<iot_application::CUserInfo> &listUserInfo, void *pUserData)
|
||||
void CAcsDevice::handleSetUserInfoResult(const std::list<iot_app::CUserInfo> &listUserInfo, void *pUserData)
|
||||
{
|
||||
(void) listUserInfo;
|
||||
(void) pUserData;
|
||||
@ -345,4 +345,4 @@ void CAcsDevice::processStateMachine()
|
||||
}
|
||||
}
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -15,12 +15,12 @@
|
||||
#include "net_msg_bus_api/MsgBusApi.h"
|
||||
#include "app_bio_identify/acs_device_api/CAcsDeviceApi.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
class CAcsWorkThread;
|
||||
|
||||
class CAcsDevice : private iot_application::CAcsDeviceApi
|
||||
class CAcsDevice : private iot_app::CAcsDeviceApi
|
||||
{
|
||||
public:
|
||||
CAcsDevice(CAcsWorkThread *pParent, const char *szTagName,
|
||||
@ -70,7 +70,7 @@ private:
|
||||
|
||||
void handleFingerprintInfo(bool bSuccess, size_t nDataLen, const char *pData, void *pUserData) override;
|
||||
|
||||
void handleSetUserInfoResult(const std::list<iot_application::CUserInfo> &listUserInfo, void *pUserData) override;
|
||||
void handleSetUserInfoResult(const std::list<iot_app::CUserInfo> &listUserInfo, void *pUserData) override;
|
||||
|
||||
void handleIdentificationEvent(bool bPass, int nUserID, size_t nPicDataLen, const char *pPicData) override;
|
||||
|
||||
@ -104,5 +104,5 @@ private:
|
||||
|
||||
typedef boost::shared_ptr<CAcsDevice> CAcsDevicePtr;
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
#include "CAcsWorkThread.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
CAcsWorkThread::CAcsWorkThread() :
|
||||
@ -276,5 +276,5 @@ void CAcsWorkThread::handleOneMbMsg()
|
||||
}
|
||||
}
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
#include "CAcsDevice.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
class CAcsWorkThread : private iot_public::CTimerThreadBase
|
||||
@ -59,5 +59,5 @@ private:
|
||||
std::map<std::string, CAcsDevicePtr> m_mapAcsDevice;
|
||||
};
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
#define BIS_PROC_NAME "app_bio_identify_srv"
|
||||
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
CBioIdentifySrv::CBioIdentifySrv()
|
||||
@ -346,5 +346,5 @@ int CBioIdentifySrv::getDomainID() const
|
||||
return m_nDomainID;
|
||||
}
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
|
||||
#include "CBisRedunSw.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
class CBioIdentifySrv : public iot_public::CBaseService, iot_sys::CProcessQuitInterface
|
||||
@ -63,5 +63,5 @@ private:
|
||||
iot_sys::CRedundantMngInterfacePtr m_ptrRedundantMng;
|
||||
};
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
|
||||
@ -11,9 +11,9 @@
|
||||
|
||||
#include "CBisRedunSw.h"
|
||||
|
||||
extern iot_application::CBioIdentifySrv *g_pBioIdentifySrv;
|
||||
extern iot_app::CBioIdentifySrv *g_pBioIdentifySrv;
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
CBisRedunSw::CBisRedunSw()
|
||||
@ -43,5 +43,5 @@ int CBisRedunSw::redundantSwitch(bool bMaster, bool bSlave)
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
#include "CAcsWorkThread.h"
|
||||
|
||||
namespace iot_application
|
||||
namespace iot_app
|
||||
{
|
||||
|
||||
class CBisRedunSw : public ::iot_sys::CRedundantSwitchInterface
|
||||
@ -32,5 +32,5 @@ private:
|
||||
|
||||
typedef boost::shared_ptr<CBisRedunSw> CCBisRedunSwPtr;
|
||||
|
||||
} //< namespace iot_application
|
||||
} //< namespace iot_app
|
||||
|
||||
|
||||
@ -9,11 +9,11 @@
|
||||
|
||||
#include "CBioIdentifySrv.h"
|
||||
|
||||
iot_application::CBioIdentifySrv *g_pBioIdentifySrv = nullptr;
|
||||
iot_app::CBioIdentifySrv *g_pBioIdentifySrv = nullptr;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
iot_application::CBioIdentifySrv objApp;
|
||||
iot_app::CBioIdentifySrv objApp;
|
||||
g_pBioIdentifySrv = &objApp;
|
||||
return objApp.main(argc, argv);
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
using namespace iot_application;
|
||||
using namespace iot_app;
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent), ui(new Ui::MainWindow)
|
||||
@ -12,7 +12,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
ui->setupUi(this);
|
||||
|
||||
qRegisterMetaType<std::string>("std::string");
|
||||
qRegisterMetaType<std::list<iot_application::CUserInfo>>("std::list<iot_application::CUserInfo>");
|
||||
qRegisterMetaType<std::list<iot_app::CUserInfo>>("std::list<iot_app::CUserInfo>");
|
||||
qRegisterMetaType<size_t>("size_t");
|
||||
|
||||
connect(this, SIGNAL(faceInfoFinish(bool, std::string, void * )),
|
||||
@ -21,8 +21,8 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
connect(this, SIGNAL(fingerprintInfoFinish(bool, std::string, void * )),
|
||||
this, SLOT(on_fingerprintInfoFinish(bool, std::string, void * )));
|
||||
|
||||
connect(this, SIGNAL(setUserInfoFinish(std::list<iot_application::CUserInfo>, void * )),
|
||||
this, SLOT(on_setUserInfoFinish(std::list<iot_application::CUserInfo>, void * )));
|
||||
connect(this, SIGNAL(setUserInfoFinish(std::list<iot_app::CUserInfo>, void * )),
|
||||
this, SLOT(on_setUserInfoFinish(std::list<iot_app::CUserInfo>, void * )));
|
||||
|
||||
connect(this, SIGNAL(identificationEvent(bool, int, size_t, const char *)),
|
||||
this, SLOT(on_identificationEvent(bool, int, size_t, const char *)));
|
||||
@ -49,7 +49,7 @@ void MainWindow::handleFingerprintInfo(bool bSuccess, size_t nDataLen, const cha
|
||||
emit fingerprintInfoFinish(bSuccess, strData, pUserData);
|
||||
}
|
||||
|
||||
void MainWindow::handleSetUserInfoResult(const std::list<iot_application::CUserInfo> &listUserInfo, void *pUserData)
|
||||
void MainWindow::handleSetUserInfoResult(const std::list<iot_app::CUserInfo> &listUserInfo, void *pUserData)
|
||||
{
|
||||
emit setUserInfoFinish(listUserInfo, pUserData);
|
||||
}
|
||||
@ -131,13 +131,13 @@ void MainWindow::on_fingerprintInfoFinish(bool bSuccess, std::string strData, vo
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_setUserInfoFinish(std::list<iot_application::CUserInfo> listUserInfo, void *pUserData)
|
||||
void MainWindow::on_setUserInfoFinish(std::list<iot_app::CUserInfo> listUserInfo, void *pUserData)
|
||||
{
|
||||
(void) pUserData;
|
||||
|
||||
bool bSuccess = true;
|
||||
|
||||
for (std::list<iot_application::CUserInfo>::const_iterator itUser = listUserInfo.cbegin();
|
||||
for (std::list<iot_app::CUserInfo>::const_iterator itUser = listUserInfo.cbegin();
|
||||
listUserInfo.cend() != itUser; ++itUser)
|
||||
{
|
||||
if (!itUser->m_bSetCarSuccess)
|
||||
@ -157,8 +157,8 @@ void MainWindow::on_setUserInfoFinish(std::list<iot_application::CUserInfo> list
|
||||
itUser->m_strName.c_str()));
|
||||
}
|
||||
|
||||
const std::list<iot_application::CFingerprintInfo> &listFp = itUser->m_listFingerprint;
|
||||
for (std::list<iot_application::CFingerprintInfo>::const_iterator itFp = listFp.cbegin();
|
||||
const std::list<iot_app::CFingerprintInfo> &listFp = itUser->m_listFingerprint;
|
||||
for (std::list<iot_app::CFingerprintInfo>::const_iterator itFp = listFp.cbegin();
|
||||
listFp.cend() != itFp; ++itFp)
|
||||
{
|
||||
if (!itFp->m_bSetSuccess)
|
||||
@ -187,7 +187,7 @@ void MainWindow::on_identificationEvent(bool bPass, int nUserID, size_t nPicData
|
||||
|
||||
void MainWindow::on_btnLogin_clicked()
|
||||
{
|
||||
if (logInToDevice("192.168.79.135", 8000, "admin", "kbdct@0755"))
|
||||
if (logInToDevice("192.168.79.135", 8000, "admin", EMS_DEFAULT_PASSWD))
|
||||
{
|
||||
QMessageBox::information(this, "", "登录成功!");
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ class MainWindow;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class MainWindow : public QMainWindow, private iot_application::CAcsDeviceApi
|
||||
class MainWindow : public QMainWindow, private iot_app::CAcsDeviceApi
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -25,7 +25,7 @@ private:
|
||||
|
||||
void handleFingerprintInfo(bool bSuccess, size_t nDataLen, const char *pData, void *pUserData) override;
|
||||
|
||||
void handleSetUserInfoResult(const std::list<iot_application::CUserInfo> &listUserInfo, void *pUserData) override;
|
||||
void handleSetUserInfoResult(const std::list<iot_app::CUserInfo> &listUserInfo, void *pUserData) override;
|
||||
|
||||
void handleIdentificationEvent(bool bPass, int nUserID, size_t nPicDataLen, const char *pPicData) override;
|
||||
|
||||
@ -34,7 +34,7 @@ signals:
|
||||
|
||||
void fingerprintInfoFinish(bool bSuccess, std::string strData, void *pUserData);
|
||||
|
||||
void setUserInfoFinish(std::list<iot_application::CUserInfo> listUserInfo, void *pUserData);
|
||||
void setUserInfoFinish(std::list<iot_app::CUserInfo> listUserInfo, void *pUserData);
|
||||
|
||||
void identificationEvent(bool bPass, int nUserID, size_t nPicDataLen, const char *pPicData);
|
||||
|
||||
@ -44,7 +44,7 @@ private slots:
|
||||
|
||||
void on_fingerprintInfoFinish(bool bSuccess, std::string strData, void *pUserData);
|
||||
|
||||
void on_setUserInfoFinish(std::list<iot_application::CUserInfo> listUserInfo, void *pUserData);
|
||||
void on_setUserInfoFinish(std::list<iot_app::CUserInfo> listUserInfo, void *pUserData);
|
||||
|
||||
void on_identificationEvent(bool bPass, int nUserID, size_t nPicDataLen, const char *pPicData);
|
||||
|
||||
|
||||
@ -5,8 +5,19 @@
|
||||
*/
|
||||
|
||||
#include "boost/filesystem.hpp"
|
||||
|
||||
//< 屏蔽xml_parser编译告警
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-copy"
|
||||
#endif
|
||||
|
||||
#include "boost/property_tree/xml_parser.hpp"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "common/Common.h"
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "pub_utility_api/FileUtil.h"
|
||||
|
||||
@ -50,6 +50,8 @@ CFbdGrpWorkThread::CFbdGrpWorkThread( CFbdUtilPtr ptrFbdUtil, const SFbdGroupInf
|
||||
m_stGrpInfo( stGrpInfo )
|
||||
{
|
||||
//< 其他成员变量已在头文件设置初值
|
||||
setDiagram(m_stGrpInfo.m_nId);
|
||||
setDiagOptCmdApi();
|
||||
}
|
||||
|
||||
|
||||
@ -66,6 +68,10 @@ CFbdGrpWorkThread::~CFbdGrpWorkThread()
|
||||
m_mapDllHandle.clear();
|
||||
m_ptrFbdUtil.reset();
|
||||
|
||||
if( m_ptrDiagOptCmd != nullptr )
|
||||
{
|
||||
m_ptrDiagOptCmd->removeGroup(m_vecDiagram);
|
||||
}
|
||||
delete m_pMbComm;
|
||||
m_pMbComm = nullptr;
|
||||
}
|
||||
@ -83,6 +89,10 @@ void CFbdGrpWorkThread::execute()
|
||||
it.second->calculate();
|
||||
}
|
||||
m_nLastRunFbdUtc = iot_public::getUTCTimeMsec();
|
||||
if( m_ptrDiagOptCmd != nullptr )
|
||||
{
|
||||
m_ptrDiagOptCmd->trigerSendMessage(m_vecDiagram);
|
||||
}
|
||||
}
|
||||
|
||||
//< 接收并响应调试消息
|
||||
@ -334,5 +344,21 @@ int CFbdGrpWorkThread::resetModule( bool bMaster )
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CFbdGrpWorkThread::setDiagram(const int groupId)
|
||||
{
|
||||
return m_ptrFbdUtil->getDiagramNameFromDB(groupId,m_vecDiagram);
|
||||
}
|
||||
|
||||
int CFbdGrpWorkThread::setDiagOptCmdApi()
|
||||
{
|
||||
m_ptrDiagOptCmd = getFbdDiagOptCmdApi();
|
||||
if ( m_ptrDiagOptCmd == nullptr )
|
||||
{
|
||||
LOGERROR( "获取Diagram数据接口单例失败" );
|
||||
return iotFailed;
|
||||
}
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
} //< namespace app_fbd
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
#include "app_fbd/fbd_common/BaseModule.h"
|
||||
#include "FbdUtil.h"
|
||||
#include "app_fbd/fbd_common/FbdDiagOptCmdApi.h"
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
@ -70,6 +71,18 @@ private:
|
||||
*/
|
||||
int resetModule( bool bMaster );
|
||||
|
||||
/**
|
||||
@brief 设置当前线程运行的图表
|
||||
@param int groupId
|
||||
@return 成功返回iotSuccess,失败返回错误码
|
||||
*/
|
||||
int setDiagram(const int groupId);
|
||||
/**
|
||||
@brief 获取功能模块控制接口
|
||||
@return 成功返回iotSuccess,失败返回错误码
|
||||
*/
|
||||
int setDiagOptCmdApi();
|
||||
|
||||
private:
|
||||
struct SModInfoOrder
|
||||
{
|
||||
@ -91,7 +104,20 @@ private:
|
||||
|
||||
inline bool operator<( const SModInfoOrder &rhs ) const
|
||||
{
|
||||
return (( m_nLevel < rhs.m_nLevel ) || (( m_nLevel == rhs.m_nLevel ) && m_stModKey < rhs.m_stModKey ));
|
||||
//< 先按图排序,同一张图按层级排序,同一层级按模块名排序
|
||||
if(m_stModKey.m_strDiagName != rhs.m_stModKey.m_strDiagName)
|
||||
{
|
||||
return m_stModKey.m_strDiagName < rhs.m_stModKey.m_strDiagName;
|
||||
}
|
||||
else if(m_nLevel != rhs.m_nLevel)
|
||||
{
|
||||
return m_nLevel < rhs.m_nLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_stModKey.m_strModName < rhs.m_stModKey.m_strModName;
|
||||
}
|
||||
//return (( m_nLevel < rhs.m_nLevel ) || (( m_nLevel == rhs.m_nLevel ) && m_stModKey < rhs.m_stModKey ));
|
||||
}
|
||||
|
||||
};
|
||||
@ -110,6 +136,9 @@ private:
|
||||
|
||||
std::map<std::string, PluginApiFunc> m_mapDllHandle; //< 本组加载的动态库
|
||||
std::map<SModInfoOrder, CBaseModulePtr> m_mapFuncPtr; //< 本组管理的所有模块对应的对象
|
||||
|
||||
std::vector<std::string> m_vecDiagram;//本组管理的图表名
|
||||
CFbdDiagOptCmdApiPtr m_ptrDiagOptCmd; //< Diagram数据接口
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<CFbdGrpWorkThread> CFbdGrpWorkThreadPtr;
|
||||
|
||||
@ -287,7 +287,7 @@ bool CFbdServerApp::initialize()
|
||||
//< 初始化翻译
|
||||
if ( iot_public::initI18N( "/app_fbd/translate", "app_fbd" ))
|
||||
{
|
||||
LOGDEBUG( I18N_C( "I18N test:\n This is src hardcode. \n int = [%d] , str = [%s]\n" ), 123, "test" );
|
||||
//LOGDEBUG( I18N_C( "I18N test:\n This is src hardcode. \n int = [%d] , str = [%s]\n" ), 123, "test" );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -460,5 +460,38 @@ int CFbdUtil::getGroupDataFromDB( const std::vector<SFbdGroupInfo> &vecGrpInfo,
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CFbdUtil::getDiagramNameFromDB(const int groupId, std::vector<std::string> &vecDiagramName)
|
||||
{
|
||||
//< 析构时会自动关闭连接
|
||||
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
|
||||
if ( !objDbConn.open())
|
||||
{
|
||||
LOGERROR( "打开数据库失败" );
|
||||
return iotFailed;
|
||||
}
|
||||
LOGINFO( "数据库地址=[%s],名称=[%s]", objDbConn.getCurrentDbPara().getHostName().toUtf8().data(),
|
||||
objDbConn.getCurrentDbPara().getDatabaseName().toUtf8().data());
|
||||
|
||||
const QString strCol = objDbConn.addQuoteMarks( "NAME" )+ "," + objDbConn.addQuoteMarks( "ENABLE" );
|
||||
|
||||
const QString strSql=QString( "SELECT %1 FROM %2 WHERE %3 = %4 " )
|
||||
.arg( strCol )
|
||||
.arg( objDbConn.addQuoteMarks( "FBD_DIAGRAM" ))
|
||||
.arg( objDbConn.addQuoteMarks( "GROUP_ID" ))
|
||||
.arg( groupId );
|
||||
|
||||
QSqlQuery objQuery;
|
||||
if ( !objDbConn.execute( strSql, objQuery ))
|
||||
{
|
||||
LOGERROR( "查询错误,SQL语句如下:\n%s", strSql.toUtf8().constData());
|
||||
return iotFailed;
|
||||
}
|
||||
while (objQuery.next()) {
|
||||
std::string strDiagName = objQuery.value( "NAME" ).toString().toStdString();
|
||||
vecDiagramName.push_back(strDiagName);
|
||||
}
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
} //< namespace app_fbd
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -60,11 +60,19 @@ public:
|
||||
@brief 从关系库获取指定fbd组的相关配置信息
|
||||
@param vecGrpInfo 要获取的FBD组列表
|
||||
@param mapGrpData 返回的FBD组相关信息
|
||||
@param vecDiagramName 返回的FBD组正在运行的图表名
|
||||
@return 成功返回iotSuccess,失败返回错误码
|
||||
*/
|
||||
static int getGroupDataFromDB( const std::vector<SFbdGroupInfo> &vecGrpInfo,
|
||||
GrpIdToDataInfoMAP &mapGrpData );
|
||||
GrpIdToDataInfoMAP &mapGrpData);
|
||||
|
||||
/**
|
||||
@brief 从关系库获取指定fbd组的相关配置信息
|
||||
@param vecdiagram 要获取的图表列表的组id
|
||||
@param mapGrpData 返回的组的图表列表
|
||||
@return 成功返回iotSuccess,失败返回错误码
|
||||
*/
|
||||
static int getDiagramNameFromDB( const int groupId,std::vector<std::string> &vecDiagramName );
|
||||
|
||||
inline int getFbdGroupInfoList( std::vector<SFbdGroupInfo> &vecGrpInfo )
|
||||
{
|
||||
|
||||
@ -115,14 +115,14 @@ void CPointSubThread::execute()
|
||||
//< 使用接收消息控制运行间隔
|
||||
m_nRunPeriodMsec = 0;
|
||||
|
||||
LOGINFO( "接客啦,干劲十足!" );
|
||||
LOGINFO( "完成初始化,开始准备接收消息" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( cn_nIdleRunPeriod != m_nRunPeriodMsec )
|
||||
{
|
||||
LOGINFO( "无人问津,消极怠工..." );
|
||||
LOGINFO( "无任务处理,进入空闲模式" );
|
||||
m_nRunPeriodMsec = cn_nIdleRunPeriod;
|
||||
}
|
||||
return;
|
||||
@ -140,7 +140,7 @@ void CPointSubThread::execute()
|
||||
return;
|
||||
}
|
||||
++m_nLoopBeforClear;
|
||||
LOGINFO( "无人问津,怠工前周期计数[%d]", m_nLoopBeforClear );
|
||||
LOGTRACE( "无任务处理,空闲周期计数[%d]", m_nLoopBeforClear );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -92,13 +92,13 @@ void CAlarmCltThread::execute()
|
||||
//< 使用接收消息控制运行间隔
|
||||
m_nRunPeriodMsec = 0;
|
||||
|
||||
LOGINFO( "接客啦,干劲十足!" );
|
||||
LOGINFO( "完成初始化,开始准备接收消息" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( cn_nIdleRunPeriod != m_nRunPeriodMsec )
|
||||
{
|
||||
LOGINFO( "无人问津,消极怠工..." );
|
||||
LOGINFO( "无任务处理,进入空闲模式" );
|
||||
m_nRunPeriodMsec = cn_nIdleRunPeriod;
|
||||
}
|
||||
return;
|
||||
@ -116,7 +116,7 @@ void CAlarmCltThread::execute()
|
||||
return;
|
||||
}
|
||||
++m_nLoopBeforClear;
|
||||
LOGINFO( "无人问津,怠工前周期计数[%d]", m_nLoopBeforClear );
|
||||
LOGINFO( "无任务处理,空闲周期计数[%d]", m_nLoopBeforClear );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -79,6 +79,8 @@ CFbdDiagDataImpl::CFbdDiagDataImpl()
|
||||
m_pMutexModInputTable = new boost::shared_mutex;
|
||||
m_pMutexModOutputTable = new boost::shared_mutex;
|
||||
m_pMutexModPropTable = new boost::shared_mutex;
|
||||
|
||||
m_pMutexGlobalVarMap = new boost::shared_mutex;
|
||||
}
|
||||
|
||||
|
||||
@ -98,6 +100,9 @@ CFbdDiagDataImpl::~CFbdDiagDataImpl()
|
||||
|
||||
delete m_pMutexModPropTable;
|
||||
m_pMutexModPropTable = nullptr;
|
||||
|
||||
delete m_pMutexGlobalVarMap;
|
||||
m_pMutexGlobalVarMap = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -386,6 +391,163 @@ int CFbdDiagDataImpl::setAlarmValByKey( const SFbdValueKey &stValueKey, const SF
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CFbdDiagDataImpl::getGlobalNumericValByKey(const std::string &strVarName, SFbdNumericValue &stValAndSta) const
|
||||
{
|
||||
stValAndSta.m_nStatus = CN_FBD_STATUS_Invalid;
|
||||
//< 读锁
|
||||
boost::shared_lock<boost::shared_mutex> lock(*m_pMutexGlobalVarMap);
|
||||
auto iter = m_mapGlobalVar.find(strVarName);
|
||||
if(iter == m_mapGlobalVar.end())
|
||||
{
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
const SFbdNumericValue *pValue = boost::any_cast<SFbdNumericValue>(&(iter->second));
|
||||
if ( nullptr == pValue )
|
||||
{
|
||||
LOGERROR( "getGlobalNumericValByKey(): 类型不一致,key=[%s],type=[%s]",
|
||||
strVarName.c_str(),
|
||||
iter->second.type().name());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
stValAndSta = *pValue;
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CFbdDiagDataImpl::setGlobalNumericValByKey(const std::string &strVarName, const SFbdNumericValue &stValAndSta)
|
||||
{
|
||||
//< 写锁
|
||||
boost::unique_lock<boost::shared_mutex> lock( *m_pMutexGlobalVarMap );
|
||||
auto iter = m_mapGlobalVar.find(strVarName);
|
||||
if(iter == m_mapGlobalVar.end())
|
||||
{
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
iter->second = stValAndSta;
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CFbdDiagDataImpl::regGlobalNumericValByKey(const std::string &strVarName, const SFbdNumericValue &stValAndSta)
|
||||
{
|
||||
//< 写锁
|
||||
boost::unique_lock<boost::shared_mutex> lock( *m_pMutexGlobalVarMap );
|
||||
auto iter = m_mapGlobalVar.find(strVarName);
|
||||
if(iter != m_mapGlobalVar.end())
|
||||
{
|
||||
LOGINFO( "regGlobalNumericValByKey 变量[%s]已经存在",strVarName.c_str() );
|
||||
|
||||
//检查类型是否一致
|
||||
if(iter->second.type() != typeid(SFbdNumericValue))
|
||||
{
|
||||
LOGERROR( "regGlobalNumericValByKey(): 类型不一致,key=[%s],type=[%s]",
|
||||
strVarName.c_str(),
|
||||
iter->second.type().name());
|
||||
|
||||
return iotFBDErr_GlobalVarTypeMismatch;
|
||||
}
|
||||
|
||||
return iotFBDErr_GlobalVarAlreadyExist;
|
||||
}
|
||||
|
||||
m_mapGlobalVar[strVarName] = stValAndSta;
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CFbdDiagDataImpl::unregGlobalNumericVar(const std::string &strVarName)
|
||||
{
|
||||
//< 写锁
|
||||
boost::unique_lock<boost::shared_mutex> lock( *m_pMutexGlobalVarMap );
|
||||
auto iter = m_mapGlobalVar.find(strVarName);
|
||||
if(iter != m_mapGlobalVar.end())
|
||||
{
|
||||
m_mapGlobalVar.erase(iter);
|
||||
}
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CFbdDiagDataImpl::getGlobalStringValByKey(const std::string &strVarName, SFbdStringValue &stValAndSta) const
|
||||
{
|
||||
stValAndSta.m_nStatus = CN_FBD_STATUS_Invalid;
|
||||
//< 读锁
|
||||
boost::shared_lock<boost::shared_mutex> lock(*m_pMutexGlobalVarMap);
|
||||
auto iter = m_mapGlobalVar.find(strVarName);
|
||||
if(iter == m_mapGlobalVar.end())
|
||||
{
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
const SFbdStringValue *pValue = boost::any_cast<SFbdStringValue>(&(iter->second));
|
||||
if ( nullptr == pValue )
|
||||
{
|
||||
LOGERROR( "getGlobalStringValByKey(): 类型不一致,key=[%s],type=[%s]",
|
||||
strVarName.c_str(),
|
||||
iter->second.type().name());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
stValAndSta = *pValue;
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CFbdDiagDataImpl::setGlobalStringValByKey(const std::string &strVarName, const SFbdStringValue &stValAndSta)
|
||||
{
|
||||
//< 写锁
|
||||
boost::unique_lock<boost::shared_mutex> lock( *m_pMutexGlobalVarMap );
|
||||
auto iter = m_mapGlobalVar.find(strVarName);
|
||||
if(iter == m_mapGlobalVar.end())
|
||||
{
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
iter->second = stValAndSta;
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CFbdDiagDataImpl::regGlobalStringValByKey(const std::string &strVarName, const SFbdStringValue &stValAndSta)
|
||||
{
|
||||
//< 写锁
|
||||
boost::unique_lock<boost::shared_mutex> lock( *m_pMutexGlobalVarMap );
|
||||
auto iter = m_mapGlobalVar.find(strVarName);
|
||||
if(iter != m_mapGlobalVar.end())
|
||||
{
|
||||
LOGINFO( "regGlobalStringValByKey 变量[%s]已经存在",strVarName.c_str() );
|
||||
|
||||
//检查类型是否一致
|
||||
if(iter->second.type() != typeid(SFbdStringValue))
|
||||
{
|
||||
LOGERROR( "regGlobalStringValByKey(): 类型不一致,key=[%s],type=[%s]",
|
||||
strVarName.c_str(),
|
||||
iter->second.type().name());
|
||||
|
||||
return iotFBDErr_GlobalVarTypeMismatch;
|
||||
}
|
||||
|
||||
return iotFBDErr_GlobalVarAlreadyExist;
|
||||
}
|
||||
|
||||
m_mapGlobalVar[strVarName] = stValAndSta;
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CFbdDiagDataImpl::unregGlobalStringVar(const std::string &strVarName)
|
||||
{
|
||||
//< 写锁
|
||||
boost::unique_lock<boost::shared_mutex> lock( *m_pMutexGlobalVarMap );
|
||||
auto iter = m_mapGlobalVar.find(strVarName);
|
||||
if(iter != m_mapGlobalVar.end())
|
||||
{
|
||||
m_mapGlobalVar.erase(iter);
|
||||
}
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
|
||||
@ -62,6 +62,30 @@ public:
|
||||
//< 见基类说明
|
||||
int setAlarmValByKey( const SFbdValueKey &stValueKey, const SFbdAlarmValue &stValAndSta ) override;
|
||||
|
||||
//< 见基类说明
|
||||
int getGlobalNumericValByKey( const std::string &strVarName, SFbdNumericValue &stValAndSta ) const override;
|
||||
|
||||
//< 见基类说明
|
||||
int setGlobalNumericValByKey( const std::string &strVarName,const SFbdNumericValue &stValAndSta ) override;
|
||||
|
||||
//< 见基类说明
|
||||
int regGlobalNumericValByKey( const std::string &strVarName,const SFbdNumericValue &stValAndSta ) override;
|
||||
|
||||
//< 见基类说明
|
||||
int unregGlobalNumericVar(const std::string &strVarName) override;
|
||||
|
||||
//< 见基类说明
|
||||
int getGlobalStringValByKey( const std::string &strVarName,SFbdStringValue &stValAndSta ) const override;
|
||||
|
||||
//< 见基类说明
|
||||
int setGlobalStringValByKey( const std::string &strVarName,const SFbdStringValue &stValAndSta ) override;
|
||||
|
||||
//< 见基类说明
|
||||
int regGlobalStringValByKey( const std::string &strVarName,const SFbdStringValue &stValAndSta ) override;
|
||||
|
||||
//< 见基类说明
|
||||
int unregGlobalStringVar(const std::string &strVarName) override;
|
||||
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
@ -94,6 +118,9 @@ private:
|
||||
SFbdModInputPtrContainer m_objModInputTable;
|
||||
SFbdModOutputPtrContainer m_objModOutputTable;
|
||||
SFbdModPropertyPtrContainer m_objModPropTable;
|
||||
|
||||
boost::shared_mutex *m_pMutexGlobalVarMap{nullptr};
|
||||
GlobalVarHashMAP m_mapGlobalVar; //存储全局变量
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<CFbdDiagDataImpl> CFbdDiagDataImplPtr;
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
//#include "boost/multi_index/hashed_index.hpp"
|
||||
#include "boost/multi_index/ordered_index.hpp"
|
||||
//#include "boost/multi_index/sequenced_index.hpp"
|
||||
|
||||
#include "boost/unordered_map.hpp"
|
||||
#include "app_fbd/fbd_common/FbdDiagDataStruct.h"
|
||||
|
||||
namespace iot_app
|
||||
@ -274,5 +274,7 @@ struct SFbdGroupData
|
||||
std::vector<SFbdModPropertyPtr> m_vecPtrModProp;
|
||||
};
|
||||
|
||||
typedef boost::unordered_map<std::string,boost::any> GlobalVarHashMAP;
|
||||
|
||||
} //< namespace app_fbd
|
||||
} //< namespace iot_app
|
||||
|
||||
@ -0,0 +1,402 @@
|
||||
/*********************************************************************************
|
||||
* @file FbdDiagOptCmdImpl.cpp
|
||||
* @brief 功能块图(Diagram)控制接口实现
|
||||
* @author caodingfa
|
||||
* @version 1.0
|
||||
* @date 2024/10/23
|
||||
**********************************************************************************/
|
||||
|
||||
#include "boost/weak_ptr.hpp"
|
||||
#include "FbdDiagOptCmdImpl.h"
|
||||
#include "common/Common.h"
|
||||
#include "pub_utility_api/CharUtil.h"
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "common/MessageChannel.h"
|
||||
#include "app_fbd/fbd_common/FbdSysInfoApi.h"
|
||||
#include "pub_utility_api/TimeUtil.h"
|
||||
#include <boost/format.hpp>
|
||||
|
||||
using namespace iot_public;
|
||||
using namespace iot_net;
|
||||
using namespace std;
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
namespace app_fbd
|
||||
{
|
||||
|
||||
static const int cn_nIdleRunPeriod = 1000; //< 空闲时的运行周期
|
||||
static const int CN_CB_SIZE = 100; //< 每个图元环形缓冲区的大小
|
||||
static const int ASYNC_CACHE_SIZE = 2000; //< 异步缓冲区
|
||||
|
||||
//< 弱指针,观察者模式
|
||||
static boost::weak_ptr<CFbdDiagOptCmdImpl> g_wpSingleton;
|
||||
|
||||
//< 保护 g_wpSingleton
|
||||
static boost::mutex g_mutexSingleton;
|
||||
|
||||
//< 获取单例
|
||||
FBD_COMMON_API CFbdDiagOptCmdApiPtr getFbdDiagOptCmdApi()
|
||||
{
|
||||
CFbdDiagOptCmdImplPtr spInst = g_wpSingleton.lock();
|
||||
if ( nullptr != spInst )
|
||||
return spInst;
|
||||
|
||||
boost::mutex::scoped_lock lock( g_mutexSingleton );
|
||||
spInst = g_wpSingleton.lock();
|
||||
if ( nullptr != spInst )
|
||||
return spInst;
|
||||
|
||||
spInst = boost::make_shared<CFbdDiagOptCmdImpl>();
|
||||
|
||||
if ( iotSuccess == spInst->initialize())
|
||||
{
|
||||
g_wpSingleton = spInst;
|
||||
return spInst;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
|
||||
CFbdDiagOptCmdImpl::CFbdDiagOptCmdImpl()
|
||||
:iot_public::CTimerThreadBase("控制命令反馈",0), //依赖消息总线的超时
|
||||
m_pMbComm(NULL),
|
||||
m_pPublisherMbComm(NULL)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CFbdDiagOptCmdImpl::~CFbdDiagOptCmdImpl()
|
||||
{
|
||||
CTimerThreadBase::quit();
|
||||
|
||||
if(m_pMbComm != NULL)
|
||||
{
|
||||
delete m_pMbComm;
|
||||
m_pMbComm = NULL;
|
||||
}
|
||||
if(m_pPublisherMbComm != NULL)
|
||||
{
|
||||
delete m_pPublisherMbComm;
|
||||
m_pPublisherMbComm = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CFbdDiagOptCmdImpl::execute()
|
||||
{
|
||||
{
|
||||
//< 读锁,正常情况不会出现m_pMbComm为NULL时线程还运行的情况
|
||||
boost::mutex::scoped_lock lock(m_objResourceMutex);
|
||||
if(m_pMbComm == NULL)
|
||||
{
|
||||
LOGERROR( "通讯器指针为空,非预期,检查程序!" );
|
||||
return; //< 正常情况不会进入此处
|
||||
}
|
||||
}
|
||||
|
||||
iot_net::CMbMessage objMsg;
|
||||
while ( m_pMbComm->recvMsg( objMsg, 100 ))
|
||||
{
|
||||
SOptCtrlReplyPtr ptrOptRep = boost::make_shared<SOptCtrlReply>();
|
||||
|
||||
const std::string strMsg(( const char * ) objMsg.getDataPtr(), objMsg.getDataSize());
|
||||
if ( !COptCtrlReply::parse( strMsg, *ptrOptRep ))
|
||||
{
|
||||
LOGERROR( "反馈命令解析失败" );
|
||||
continue;
|
||||
}
|
||||
|
||||
putMsgToCache(ptrOptRep);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CFbdDiagOptCmdImpl::initialize()
|
||||
{
|
||||
m_strHostName = getFbdSysInfoApi()->getCurrentRunAppInfo().strLocalNodeName;
|
||||
|
||||
if(m_strHostName.empty())
|
||||
{
|
||||
LOGERROR("CFbdDiagOptCmdImpl 获取本节点名失败");
|
||||
return iotFailed;
|
||||
}
|
||||
m_pPublisherMbComm = new CMbCommunicator;
|
||||
if(m_pPublisherMbComm == NULL)
|
||||
{
|
||||
LOGERROR("CFbdDiagOptCmdImpl 创建发布者消息总线通信器失败");
|
||||
return iotFailed;
|
||||
}
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
bool CFbdDiagOptCmdImpl::subOptCtrlReplyTopic(const string &strInstName)
|
||||
{
|
||||
if(strInstName.empty())
|
||||
{
|
||||
LOGERROR("CFbdDiagOptCmdImpl 订阅命令反馈通道失败,实例名为空");
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::mutex::scoped_lock lock(m_objResourceMutex);
|
||||
|
||||
if(NULL == m_pMbComm)
|
||||
{
|
||||
m_pMbComm = new CMbCommunicator;
|
||||
if(m_pMbComm == NULL)
|
||||
{
|
||||
LOGERROR("CFbdDiagOptCmdImpl 创建消息总线通信器失败");
|
||||
return false;
|
||||
}
|
||||
//< 必须订阅所有专业,因为可能控制其他专业的测点
|
||||
if(!m_pMbComm->addSub(0,CH_OPT_TO_HMI_OPTCMD_UP))
|
||||
{
|
||||
LOGERROR("CFbdDiagOptCmdImpl订阅通道失败,appId=0,chanId=CH_OPT_TO_HMI_OPTCMD_UP");
|
||||
return false;
|
||||
}
|
||||
|
||||
//< 同时激活线程
|
||||
CTimerThreadBase::m_nRunPeriodMsec = 0;
|
||||
CTimerThreadBase::resume();
|
||||
|
||||
}
|
||||
|
||||
//< 建立该图元的缓冲区
|
||||
if(m_mapOptCtrlReply.count(strInstName) == 0)
|
||||
{
|
||||
boost::circular_buffer<SOptCtrlReplyPtr> cb(CN_CB_SIZE);
|
||||
m_mapOptCtrlReply[strInstName].swap(cb);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFbdDiagOptCmdImpl::unsubOptCtrlReplyTopic(const string &strInstName)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_objResourceMutex);
|
||||
m_mapOptCtrlReply.erase(strInstName);
|
||||
|
||||
if(m_mapOptCtrlReply.empty())
|
||||
{
|
||||
CTimerThreadBase::suspend(); //< 先挂起线程,防止多线程访问修改公共变量
|
||||
CTimerThreadBase::m_nRunPeriodMsec = cn_nIdleRunPeriod;
|
||||
|
||||
//< 没有订阅的图元,则销毁通信器,同时挂起线程
|
||||
delete m_pMbComm;
|
||||
m_pMbComm = NULL;
|
||||
LOGINFO("CFbdDiagOptCmdImpl 无图元订阅命令反馈通道,销毁通信器");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SOptCtrlReplyPtr CFbdDiagOptCmdImpl::getOptCtrlReply(const string &strInstName)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_objResourceMutex);
|
||||
auto iter = m_mapOptCtrlReply.find(strInstName);
|
||||
if(iter == m_mapOptCtrlReply.end())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
boost::circular_buffer<SOptCtrlReplyPtr> &buf = iter->second;
|
||||
if(buf.empty())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SOptCtrlReplyPtr ptrReply = buf.front();
|
||||
buf.pop_front();
|
||||
|
||||
return ptrReply;
|
||||
}
|
||||
|
||||
bool CFbdDiagOptCmdImpl::sendOptCtrReqToDomain(CMbMessage &msgSend, const int nDomainID)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_objResourceMutex);
|
||||
if(m_pMbComm == NULL)
|
||||
{
|
||||
LOGERROR("CFbdDiagOptCmdImpl 消息总线通信器未初始化");
|
||||
return false;
|
||||
}
|
||||
if(!m_pMbComm->sendMsgToDomain( msgSend, nDomainID ))
|
||||
{
|
||||
LOGERROR("CFbdDiagOptCmdImpl 发送控制请求报文失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string CFbdDiagOptCmdImpl::getMbCommName()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_objResourceMutex);
|
||||
if(NULL == m_pMbComm)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return m_pMbComm->getName();
|
||||
}
|
||||
|
||||
void CFbdDiagOptCmdImpl::putMsgToCache(const SOptCtrlReplyPtr ptrReply)
|
||||
{
|
||||
if(ptrReply->stHead.strHostName != m_strHostName)
|
||||
{
|
||||
return; //非本节点消息
|
||||
}
|
||||
|
||||
boost::mutex::scoped_lock lock(m_objResourceMutex);
|
||||
auto iter = m_mapOptCtrlReply.find(ptrReply->stHead.strInstName);
|
||||
if(iter == m_mapOptCtrlReply.end())
|
||||
{
|
||||
return; //无图元订阅
|
||||
}
|
||||
|
||||
boost::circular_buffer<SOptCtrlReplyPtr> &buf = iter->second;
|
||||
buf.push_back(ptrReply);
|
||||
}
|
||||
|
||||
bool CFbdDiagOptCmdImpl::pushOptCtrlMessageCache(SOptCtrlRequest msgSend,const std::string diagName,const int nAppId)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_objAsyncResourceMutex);
|
||||
|
||||
std::string strDomainAndApp = boost::str(boost::format("%d-%d") % msgSend.stHead.nDstDomainID % nAppId);
|
||||
if(m_optCtrlMessageCache.count(diagName)==0)
|
||||
{
|
||||
m_optCtrlMessageCache[diagName][strDomainAndApp]=msgSend;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(0!=m_optCtrlMessageCache[diagName].count(strDomainAndApp))
|
||||
{
|
||||
auto ctrl=msgSend.vecOptCtrlQueue[0];
|
||||
SOptCtrlRequest& existMessage=m_optCtrlMessageCache[diagName][strDomainAndApp];
|
||||
existMessage.vecOptCtrlQueue.push_back(ctrl);
|
||||
checkOptCtrlMessageSize(existMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_optCtrlMessageCache[diagName][strDomainAndApp]=msgSend;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFbdDiagOptCmdImpl::trigerSendMessage(const std::vector<std::string> vecDiagName)
|
||||
{
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_objAsyncResourceMutex);
|
||||
|
||||
sendOptCtrlMessage(vecDiagName);
|
||||
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
bool CFbdDiagOptCmdImpl::removeGroup(const std::vector<std::string> vecDiagName)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_objAsyncResourceMutex);
|
||||
for (auto it = vecDiagName.begin(); it != vecDiagName.end(); ++it) {
|
||||
if(0!=m_optCtrlMessageCache.count(*it))
|
||||
{
|
||||
m_optCtrlMessageCache.erase(*it);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFbdDiagOptCmdImpl::sendMsgToDomainByPublishCommunicator(CMbMessage &msgSend, const int nDomainID)
|
||||
{
|
||||
return m_pPublisherMbComm->sendMsgToDomain( msgSend, nDomainID);
|
||||
}
|
||||
|
||||
void CFbdDiagOptCmdImpl::checkOptCtrlMessageSize(SOptCtrlRequest &request)
|
||||
{
|
||||
if(request.vecOptCtrlQueue.size()>ASYNC_CACHE_SIZE)
|
||||
{
|
||||
request.vecOptCtrlQueue.erase(request.vecOptCtrlQueue.begin());
|
||||
}
|
||||
}
|
||||
|
||||
void CFbdDiagOptCmdImpl::sendOptCtrlMessage(const std::vector<std::string> vecDiagName)
|
||||
{
|
||||
|
||||
for (auto it = vecDiagName.begin(); it != vecDiagName.end(); ++it) {
|
||||
|
||||
if(0!=m_optCtrlMessageCache.count(*it))
|
||||
{
|
||||
auto& ctrlMessageMap=m_optCtrlMessageCache[*it];
|
||||
|
||||
for(auto itMessage = ctrlMessageMap.begin(); itMessage !=ctrlMessageMap.end(); ++itMessage)
|
||||
{
|
||||
//修正表头信息进行发送
|
||||
SOptCtrlRequest& request=itMessage->second;
|
||||
std::string strDomainAndApp=itMessage->first;
|
||||
request.stHead.strSrcTag = "CFbdDiagOptCmdImpl_Async";
|
||||
request.stHead.nUserID = 1; //< 用户ID,默认1 管理员
|
||||
request.stHead.nUserGroupID = 1; //< 用户组ID,默认1 管理员
|
||||
request.stHead.nOptTime =iot_public::getUTCTimeMsec();
|
||||
request.stHead.strCommName = getAsyncMbCommName();
|
||||
|
||||
std::string res = COptCtrlRequest::generate( request );
|
||||
if (res.empty())
|
||||
{
|
||||
LOGERROR( "生成控制报文失败。time=[%d]", request.stHead.nOptTime);
|
||||
continue;
|
||||
}
|
||||
|
||||
int nDstDomainId=0;
|
||||
int nAppId=0;
|
||||
size_t pos = strDomainAndApp.find('-');
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
nDstDomainId = std::stoi(strDomainAndApp.substr(0, pos));
|
||||
nAppId = std::stoi(strDomainAndApp.substr(pos + 1));
|
||||
}
|
||||
|
||||
iot_net::CMbMessage objMsg( res, nAppId,
|
||||
CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_AUTO_CTRL_WITHOUT_RESP );
|
||||
|
||||
if(!m_pPublisherMbComm->sendMsgToDomain( objMsg, nDstDomainId))
|
||||
{
|
||||
LOGERROR("CFbdDiagOptCmdImpl_Async 发送控制请求报文失败,消息依旧会被清空 %s",res.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGDEBUG("CFbdDiagOptCmdImpl_Async 发送控制请求报文成功 %s",res.data());
|
||||
}
|
||||
//清空队列消息
|
||||
request.vecOptCtrlQueue.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
string CFbdDiagOptCmdImpl::getAsyncMbCommName()
|
||||
{
|
||||
|
||||
if(NULL == m_pPublisherMbComm)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return m_pPublisherMbComm->getName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} //< namespace app_fbd
|
||||
} //< namespace iot_app
|
||||
@ -0,0 +1,93 @@
|
||||
/*********************************************************************************
|
||||
* @file FbdDiagOptCmdImpl.h
|
||||
* @brief 功能块图(Diagram)控制接口实现
|
||||
* @author caodingfa
|
||||
* @version 1.0
|
||||
* @date 2024/10/23
|
||||
**********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "app_fbd/fbd_common/FbdDiagOptCmdApi.h"
|
||||
#include "pub_utility_api/TimerThreadBase.h"
|
||||
#include <set>
|
||||
#include "boost/circular_buffer.hpp"
|
||||
#include "boost/unordered_map.hpp"
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
namespace app_fbd
|
||||
{
|
||||
|
||||
//< 先简单处理,只针对控制服务的反馈通道做处理
|
||||
class CFbdDiagOptCmdImpl final : public CFbdDiagOptCmdApi,public iot_public::CTimerThreadBase
|
||||
{
|
||||
public:
|
||||
CFbdDiagOptCmdImpl();
|
||||
~CFbdDiagOptCmdImpl() override;
|
||||
|
||||
/************************************************************/
|
||||
//< CTimerThreadBase相关
|
||||
|
||||
void execute() override;
|
||||
|
||||
/************************************************************/
|
||||
/**
|
||||
@brief 初始化
|
||||
@return 成功返回iotSuccess,失败返回错误码
|
||||
*/
|
||||
int initialize();
|
||||
|
||||
//< 见基类说明
|
||||
bool subOptCtrlReplyTopic(const std::string &strInstName) override;
|
||||
|
||||
//< 见基类说明
|
||||
bool unsubOptCtrlReplyTopic(const std::string &strInstName) override;
|
||||
|
||||
//< 见基类说明
|
||||
SOptCtrlReplyPtr getOptCtrlReply(const std::string &strInstName) override;
|
||||
|
||||
//< 见基类说明
|
||||
bool sendOptCtrReqToDomain(iot_net::CMbMessage &msgSend, const int nDomainID) override;
|
||||
|
||||
//< 见基类说明
|
||||
std::string getMbCommName() override;
|
||||
|
||||
//< 见基类说明
|
||||
bool pushOptCtrlMessageCache(SOptCtrlRequest msgSend,const std::string diagName,const int nAppId) override;
|
||||
|
||||
//< 见基类说明
|
||||
//直接发送
|
||||
bool trigerSendMessage(const std::vector<std::string> vecDiagName) override;
|
||||
|
||||
//< 见基类说明
|
||||
//工作线程析构时调用
|
||||
bool removeGroup(const std::vector<std::string> vecDiagName)override;
|
||||
|
||||
//< 见基类说明
|
||||
//只处理发布消息
|
||||
bool sendMsgToDomainByPublishCommunicator(iot_net::CMbMessage &msgSend, const int nDomainID )override;
|
||||
|
||||
private:
|
||||
void putMsgToCache(const SOptCtrlReplyPtr ptrReply);
|
||||
void checkOptCtrlMessageSize(SOptCtrlRequest& request);
|
||||
void sendOptCtrlMessage(const std::vector<std::string> vecDiagName);
|
||||
std::string getAsyncMbCommName();
|
||||
|
||||
typedef boost::unordered_map<std::string,SOptCtrlRequest> optCtrlMessageMap;//<dstDomainID-appId,消息类型>//头部相同的消息
|
||||
private:
|
||||
iot_net::CMbCommunicator *m_pMbComm;
|
||||
boost::mutex m_objResourceMutex;
|
||||
std::string m_strHostName;
|
||||
|
||||
boost::unordered_map<std::string,boost::circular_buffer<SOptCtrlReplyPtr> > m_mapOptCtrlReply;
|
||||
|
||||
boost::mutex m_objAsyncResourceMutex;//异步控制资源锁
|
||||
boost::unordered_map<std::string,optCtrlMessageMap> m_optCtrlMessageCache;//待发送的消息<图表名,消息队列>
|
||||
iot_net::CMbCommunicator *m_pPublisherMbComm;//只负责发布消息的通讯器
|
||||
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<CFbdDiagOptCmdImpl> CFbdDiagOptCmdImplPtr;
|
||||
|
||||
} //< namespace app_fbd
|
||||
} //< namespace iot_app
|
||||
@ -66,7 +66,7 @@ int CAlarmDataMng::getLastAlarm( SFbdAlarmInfo &stAlmOutput ) const
|
||||
|
||||
|
||||
int CAlarmDataMng::getAlarmAfter( const SFbdAlarmInfo &stPosition, std::vector<SFbdAlarmInfo> &vecOutput,
|
||||
SFbdAlarmInfo &stLastAlm ) const
|
||||
SFbdAlarmInfo &stLastAlm, const bool bIncludeBeforeStartup /*= false*/ ) const
|
||||
{
|
||||
vecOutput.clear();
|
||||
|
||||
@ -104,7 +104,7 @@ int CAlarmDataMng::getAlarmAfter( const SFbdAlarmInfo &stPosition, std::vector<S
|
||||
for ( ; indexSeq.cend() != itSeq; ++itSeq )
|
||||
{
|
||||
//< 非启动前产生的历史告警
|
||||
if ( !itSeq->m_bIsExpired )
|
||||
if (bIncludeBeforeStartup || !itSeq->m_bIsExpired )
|
||||
vecOutput.emplace_back( itSeq->m_ptrAlmInfo );
|
||||
}
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ public:
|
||||
|
||||
//< 见基类说明
|
||||
int getAlarmAfter( const SFbdAlarmInfo &stPosition, std::vector<SFbdAlarmInfo> &vecOutput,
|
||||
SFbdAlarmInfo &stLastAlm ) const;
|
||||
SFbdAlarmInfo &stLastAlm, const bool bIncludeBeforeStartup = false ) const;
|
||||
|
||||
//< 见基类说明
|
||||
int getAlarmByUuid( const std::string &strUuidBase64, SFbdAlarmInfo &stOutput ) const;
|
||||
|
||||
@ -80,9 +80,9 @@ int CFbdAlarmCltImpl::getLastAlarm( SFbdAlarmInfo &stAlmOutput ) const
|
||||
|
||||
|
||||
int CFbdAlarmCltImpl::getAlarmAfter( const SFbdAlarmInfo &stPosition, std::vector<SFbdAlarmInfo> &vecOutput,
|
||||
SFbdAlarmInfo &stLastAlm ) const
|
||||
SFbdAlarmInfo &stLastAlm,const bool bIncludeBeforeStartup/* = false*/ ) const
|
||||
{
|
||||
return m_objAlarmDataMng.getAlarmAfter( stPosition, vecOutput, stLastAlm );
|
||||
return m_objAlarmDataMng.getAlarmAfter( stPosition, vecOutput, stLastAlm, bIncludeBeforeStartup );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ public:
|
||||
|
||||
//< 见基类说明
|
||||
int getAlarmAfter( const SFbdAlarmInfo &stPosition, std::vector<SFbdAlarmInfo> &vecOutput,
|
||||
SFbdAlarmInfo &stLastAlm ) const override;
|
||||
SFbdAlarmInfo &stLastAlm,const bool bIncludeBeforeStartup = false ) const override;
|
||||
|
||||
//< 见基类说明
|
||||
int getAlarmByUuid( const std::string &strUuidBase64, SFbdAlarmInfo &stOutput ) const override;
|
||||
|
||||
@ -15,6 +15,9 @@ HEADERS += \
|
||||
../../../include/application/app_fbd/fbd_common/FbdDiagDataStruct.h \
|
||||
../../../include/application/app_fbd/fbd_common/FbdPointSubApi.h \
|
||||
../../../include/application/app_fbd/fbd_common/FbdSysInfoApi.h \
|
||||
../../../include/application/app_fbd/fbd_common/FbdDiagOptCmdApi.h \
|
||||
../../../include/service/operate_server_api/JsonMessageStruct.h \
|
||||
../../../include/service/operate_server_api/JsonOptCommand.h \
|
||||
alarm_client/AlarmDataMng.h \
|
||||
alarm_client/FbdAlarmCltImpl.h \
|
||||
alarm_client/ItlAlmDataMng.h \
|
||||
@ -22,9 +25,11 @@ HEADERS += \
|
||||
FbdDiagDataImpl.h \
|
||||
FbdDiagDataStructPrivate.h \
|
||||
FbdPointSubImpl.h \
|
||||
FbdSysInfoImpl.h
|
||||
FbdSysInfoImpl.h \
|
||||
FbdDiagOptCmdImpl.h
|
||||
|
||||
SOURCES += \
|
||||
../../../include/service/operate_server_api/JsonOptCommand.cpp \
|
||||
alarm_client/AlarmDataMng.cpp \
|
||||
alarm_client/FbdAlarmCltImpl.cpp \
|
||||
alarm_client/ItlAlmDataMng.cpp \
|
||||
@ -32,12 +37,13 @@ SOURCES += \
|
||||
FbdDiagDataImpl.cpp \
|
||||
FbdDiagDataStructPrivate.cpp \
|
||||
FbdPointSubImpl.cpp \
|
||||
FbdSysInfoImpl.cpp
|
||||
FbdSysInfoImpl.cpp \
|
||||
FbdDiagOptCmdImpl.cpp
|
||||
|
||||
|
||||
LIBS += -lboost_system -lboost_chrono -lboost_date_time -llog4cplus -lprotobuf \
|
||||
-lpub_logger_api -lrdb_api -lpub_sysinfo_api -lpub_utility_api -ldp_chg_data_api -ldata_process_api \
|
||||
-lalarm_server_api
|
||||
-lalarm_server_api -lnet_msg_bus_api
|
||||
|
||||
|
||||
include($$PWD/../../../idl_files/idl_files.pri)
|
||||
|
||||
@ -17,6 +17,7 @@ namespace app_fbd
|
||||
|
||||
CAntiShake::CAntiShake()
|
||||
: m_nLastValue( 0 ),
|
||||
m_eDelayMode(AntiShakeDelayMode_Min),
|
||||
m_lChangeTimeMsec( 0L ),
|
||||
m_ptrDiagData( nullptr )
|
||||
{
|
||||
@ -50,12 +51,72 @@ int CAntiShake::init( const SFbdModKey &stModuleKey, const std::string & )
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
//2.获取延迟输出模式
|
||||
std::string strDelayMode = "";
|
||||
if (iotSuccess != m_ptrDiagData->getModProperty(stModuleKey,"DelayMode",strDelayMode))
|
||||
{
|
||||
LOGERROR( "获取模块[%s]的DelayMode属性参数失败", stModuleKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
boost::algorithm::trim(strDelayMode);
|
||||
int nDelayMode = boost::lexical_cast<int>(strDelayMode);
|
||||
if(nDelayMode <= AntiShakeDelayMode_Min || nDelayMode >= AntiShakeDelayMode_Max)
|
||||
{
|
||||
LOGERROR( "转换模块[%s]的DelayMode属性参数失败", stModuleKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
m_eDelayMode = (AntiShakeDelayMode)nDelayMode;
|
||||
}
|
||||
catch ( const std::exception &e )
|
||||
{
|
||||
LOGERROR( "模块[%s]参数格式非法,Err:\n%s", m_stModKey.toString().c_str(), e.what());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
LOGINFO( "[%s]加载成功", m_stModKey.toString().c_str());
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
|
||||
int CAntiShake::calculate()
|
||||
{
|
||||
switch (m_eDelayMode) {
|
||||
case AntiShakeDelayMode_OutWhenInvalid:
|
||||
return calcMode_OutWhenInvalid();
|
||||
case AntiShakeDelayMode_OutWhenValid:
|
||||
return calcMode_OutWhenValid();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
|
||||
int CAntiShake::reset( const bool /*bMaster*/ )
|
||||
{
|
||||
m_lChangeTimeMsec = 0;
|
||||
SFbdNumericValue stOutput( 0, CN_FBD_STATUS_Invalid );
|
||||
|
||||
return m_ptrDiagData->setNumericValByKey( m_stOutputKey, stOutput );
|
||||
}
|
||||
|
||||
|
||||
int CAntiShake::clean()
|
||||
{
|
||||
return reset( false );
|
||||
}
|
||||
|
||||
|
||||
boost::shared_ptr<CAntiShake> CAntiShake::create()
|
||||
{
|
||||
return boost::make_shared<CAntiShake>();
|
||||
}
|
||||
|
||||
int CAntiShake::calcMode_OutWhenValid()
|
||||
{
|
||||
SFbdNumericValue stInput1( 0, CN_FBD_STATUS_Invalid );
|
||||
SFbdNumericValue stInput2( 0, CN_FBD_STATUS_Invalid );
|
||||
@ -114,25 +175,51 @@ int CAntiShake::calculate()
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
|
||||
int CAntiShake::reset( const bool /*bMaster*/ )
|
||||
int CAntiShake::calcMode_OutWhenInvalid()
|
||||
{
|
||||
m_lChangeTimeMsec = 0;
|
||||
SFbdNumericValue stOutput( 0, CN_FBD_STATUS_Invalid );
|
||||
SFbdNumericValue stInput( 0, CN_FBD_STATUS_Invalid ); //输入值
|
||||
SFbdNumericValue stTimeout( 0, CN_FBD_STATUS_Invalid ); //延迟时间
|
||||
|
||||
return m_ptrDiagData->setNumericValByKey( m_stOutputKey, stOutput );
|
||||
}
|
||||
//< 获取输入参数值和状态
|
||||
if ( iotSuccess != m_ptrDiagData->getNumericValByKey( m_stInKey1, stInput ) ||
|
||||
iotSuccess != m_ptrDiagData->getNumericValByKey( m_stInKey2, stTimeout ))
|
||||
{
|
||||
LOGERROR( "获取模块[%s]的输入参数失败", m_stModKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
//< 判断输入参数的状态是否有效,有效则直接写输出
|
||||
if ( stInput.m_nStatus == CN_FBD_STATUS_Valid)
|
||||
{
|
||||
m_lChangeTimeMsec = iot_public::getMonotonicMsec();
|
||||
return m_ptrDiagData->setNumericValByKey( m_stOutputKey, stInput );
|
||||
}
|
||||
|
||||
int CAntiShake::clean()
|
||||
{
|
||||
return reset( false );
|
||||
}
|
||||
//< 下面的代码都是基于输入值无效的情况下的运算,上面已经将有效的情况拦截了
|
||||
if ( m_lChangeTimeMsec == 0 ) //< 启动后第一次,先将输出值设置为无效,同时开始计时
|
||||
{
|
||||
SFbdNumericValue stOutputTemp( 0, CN_FBD_STATUS_Invalid );
|
||||
if ( iotSuccess != m_ptrDiagData->setNumericValByKey( m_stOutputKey, stOutputTemp ))
|
||||
{
|
||||
LOGERROR( "首次计算,写模块[%s]输出值失败", m_stModKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
m_lChangeTimeMsec = iot_public::getMonotonicMsec();
|
||||
}
|
||||
else
|
||||
{
|
||||
int64 lCurTime = iot_public::getMonotonicMsec();
|
||||
|
||||
boost::shared_ptr<CAntiShake> CAntiShake::create()
|
||||
{
|
||||
return boost::make_shared<CAntiShake>();
|
||||
//< 判断是否超时输出
|
||||
if (( lCurTime - m_lChangeTimeMsec ) > static_cast<int>(stTimeout.m_dValue))
|
||||
{
|
||||
m_lChangeTimeMsec = lCurTime;
|
||||
return m_ptrDiagData->setNumericValByKey(m_stOutputKey, stInput);
|
||||
}
|
||||
}
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
} //< namespace app_fbd
|
||||
|
||||
@ -14,6 +14,13 @@ namespace iot_app
|
||||
namespace app_fbd
|
||||
{
|
||||
|
||||
enum AntiShakeDelayMode{
|
||||
AntiShakeDelayMode_Min = -1, //无效值,用来判断枚举下限
|
||||
AntiShakeDelayMode_OutWhenInvalid = 0, //输入值无效时延迟输出无效0
|
||||
AntiShakeDelayMode_OutWhenValid, //输入值有效时输出
|
||||
AntiShakeDelayMode_Max //枚举最大值,用来判断枚举上限
|
||||
};
|
||||
|
||||
/* @brief 延迟输出模块,实现:当某值持续规定时间后输出,如果在时间内又发生了变化,重新计时 */
|
||||
class CAntiShake final : public CBaseModule
|
||||
{
|
||||
@ -32,14 +39,22 @@ public:
|
||||
// Factory method
|
||||
static boost::shared_ptr<CAntiShake> create();
|
||||
|
||||
private:
|
||||
//对应模式AntiShakeDelayMode_Valid,当输入值有效时,滤掉值抖动,也就是值不变保持一段时间才输出
|
||||
int calcMode_OutWhenValid();
|
||||
|
||||
//对应模式AntiShakeDelayMode_Invalid,当输入值无效时,延迟输出0,且状态值为无效
|
||||
int calcMode_OutWhenInvalid();
|
||||
|
||||
private:
|
||||
int m_nLastValue; //< 上一次值
|
||||
AntiShakeDelayMode m_eDelayMode; //延迟输出模式
|
||||
int64 m_lChangeTimeMsec; //< 记录值改变时间
|
||||
|
||||
CFbdDiagDataApiPtr m_ptrDiagData; //< Diagram数据接口
|
||||
|
||||
SFbdValueKey m_stInKey1; //< 输入1 key
|
||||
SFbdValueKey m_stInKey2; //< 输入2 key
|
||||
SFbdValueKey m_stInKey1; //< 输入1 key 输入值
|
||||
SFbdValueKey m_stInKey2; //< 输入2 key 延迟时间
|
||||
SFbdValueKey m_stOutputKey; //< 输出参数
|
||||
|
||||
SFbdModKey m_stModKey; //< 模块标识
|
||||
|
||||
@ -45,6 +45,13 @@ int CAoCtrl::init( const SFbdModKey &stModuleKey, const std::string & )
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
m_ptrOptCmdApi = getFbdDiagOptCmdApi();
|
||||
if( m_ptrOptCmdApi == nullptr )
|
||||
{
|
||||
LOGERROR( "获取控制反馈接口单例失败" );
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
//1.解析配置
|
||||
if ( iotSuccess != initCtrlParam())
|
||||
{
|
||||
@ -84,30 +91,12 @@ int CAoCtrl::calculate()
|
||||
{
|
||||
//< 接收消息总线消息
|
||||
{
|
||||
if ( nullptr == m_pMbComm )
|
||||
while (true)
|
||||
{
|
||||
LOGERROR( "通讯器指针为空,非预期,检查程序!" );
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
iot_net::CMbMessage objMsg;
|
||||
while ( m_pMbComm->recvMsg( objMsg, 0 ))
|
||||
{
|
||||
COptCtrlReply objParse;
|
||||
SOptCtrlReplyPtr ptrOptRep = boost::make_shared<SOptCtrlReply>();
|
||||
|
||||
const std::string strMsg(( const char * ) objMsg.getDataPtr(), objMsg.getDataSize());
|
||||
if ( !objParse.parse( strMsg, *ptrOptRep ))
|
||||
SOptCtrlReplyPtr ptrOptRep = m_ptrOptCmdApi->getOptCtrlReply(m_stModKey.toString());
|
||||
if(ptrOptRep == NULL)
|
||||
{
|
||||
LOGERROR( "反馈命令解析失败" );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ptrOptRep->stHead.strInstName != m_stModKey.toString() ||
|
||||
ptrOptRep->stHead.strHostName != getFbdSysInfoApi()->getCurrentRunAppInfo().strLocalNodeName )
|
||||
{
|
||||
//< 非本进程的反馈,丢弃
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
const auto itMap = m_mapCmdOfPnt.find( ptrOptRep->stHead.strKeyIdTag );
|
||||
@ -225,16 +214,18 @@ int CAoCtrl::reset( const bool bMaster )
|
||||
int nRet = iotSuccess;
|
||||
if ( bMaster )
|
||||
{
|
||||
if ( nullptr == m_pMbComm )
|
||||
m_pMbComm = new iot_net::CMbCommunicator;
|
||||
|
||||
//< 必须订阅所有专业,因为可能控制其他专业的测点
|
||||
m_pMbComm->addSub( 0, CH_OPT_TO_HMI_OPTCMD_UP );
|
||||
if(m_ptrOptCmdApi != NULL)
|
||||
{
|
||||
m_ptrOptCmdApi->subOptCtrlReplyTopic(m_stModKey.toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_pMbComm;
|
||||
m_pMbComm = nullptr;
|
||||
if(m_ptrOptCmdApi != NULL)
|
||||
{
|
||||
m_ptrOptCmdApi->unsubOptCtrlReplyTopic(m_stModKey.toString());
|
||||
}
|
||||
}
|
||||
|
||||
m_mapCmdOfPnt.clear(); //< 清空命令
|
||||
@ -247,11 +238,9 @@ int CAoCtrl::clean()
|
||||
{
|
||||
int nRet = reset( false );
|
||||
|
||||
m_ptrOptCmdApi.reset();
|
||||
m_ptrDiagData.reset();
|
||||
|
||||
delete m_pMbComm;
|
||||
m_pMbComm = nullptr;
|
||||
|
||||
return nRet;
|
||||
}
|
||||
|
||||
@ -356,7 +345,7 @@ void CAoCtrl::sendCtrlCmd( SCtrlCmd &stCmd, const ECmdState eSuccessState, const
|
||||
stReq.stHead.nAppID = stRunAppInfo.nAppId;
|
||||
stReq.stHead.strHostName = stRunAppInfo.strLocalNodeName;
|
||||
stReq.stHead.strInstName = m_stModKey.toString();
|
||||
stReq.stHead.strCommName = m_pMbComm->getName();
|
||||
stReq.stHead.strCommName = m_ptrOptCmdApi->getMbCommName();
|
||||
stReq.stHead.nUserID = 1; //< 用户ID,默认1 管理员
|
||||
stReq.stHead.nUserGroupID = 1; //< 用户组ID,默认1 管理员
|
||||
stReq.stHead.nOptTime = stCmd.lSendUtcMsec;
|
||||
@ -367,8 +356,7 @@ void CAoCtrl::sendCtrlCmd( SCtrlCmd &stCmd, const ECmdState eSuccessState, const
|
||||
stCtrlReq.bIsDeviceOccupy = true;
|
||||
stReq.vecOptCtrlQueue.push_back( stCtrlReq );
|
||||
|
||||
COptCtrlRequest objGen;
|
||||
stCmd.strLastSendJsonReq = objGen.generate( stReq );
|
||||
stCmd.strLastSendJsonReq = COptCtrlRequest::generate( stReq );
|
||||
if ( stCmd.strLastSendJsonReq.empty())
|
||||
{
|
||||
LOGERROR( "生成控制报文失败。KeyIdTag=[%s]", stCtrlReq.strKeyIdTag.c_str());
|
||||
@ -378,7 +366,8 @@ void CAoCtrl::sendCtrlCmd( SCtrlCmd &stCmd, const ECmdState eSuccessState, const
|
||||
|
||||
iot_net::CMbMessage objMsg( stCmd.strLastSendJsonReq, stCmd.nAppId,
|
||||
CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_AUTO_CTRL_DOWN );
|
||||
if ( m_pMbComm->sendMsgToDomain( objMsg, stCmd.nDstDomainId ))
|
||||
|
||||
if(m_ptrOptCmdApi->sendOptCtrReqToDomain(objMsg,stCmd.nDstDomainId))
|
||||
{
|
||||
stCmd.setResult( true, "发送控制命令成功", eSuccessState );
|
||||
LOGINFO( "发送控制命令到域[%d],应用[%d]成功,KeyIdTag=[%s],控制目标值[%lf]",
|
||||
@ -419,9 +408,8 @@ void CAoCtrl::waitCtrlRep( SCmdOfOnePnt &stCmdOfOnePnt, const ECmdState eSuccess
|
||||
|
||||
if ( ptrRep->stHead.nOptTime != stCurrentCmd.lSendUtcMsec )
|
||||
{
|
||||
COptCtrlReply objParse;
|
||||
LOGINFO( "时间不一致,忽略,收到的回复消息如下:\n%s",
|
||||
objParse.generate( *ptrRep ).c_str());
|
||||
COptCtrlReply::generate( *ptrRep ).c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include "operate_server_api/JsonOptCommand.h"
|
||||
#include "app_fbd/fbd_common/BaseModule.h"
|
||||
#include "app_fbd/fbd_common/FbdDiagDataApi.h"
|
||||
#include "app_fbd/fbd_common/FbdDiagOptCmdApi.h"
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
@ -140,9 +141,8 @@ private:
|
||||
int parseKeyIdTag( const std::string &strKeyIdTag, SCtrlCmd &stCtrlCmd );
|
||||
|
||||
private:
|
||||
CFbdDiagDataApiPtr m_ptrDiagData; //< Diagram数据接口
|
||||
|
||||
iot_net::CMbCommunicator *m_pMbComm{nullptr}; //< 消息总线通信器
|
||||
CFbdDiagDataApiPtr m_ptrDiagData; //< Diagram数据接口
|
||||
CFbdDiagOptCmdApiPtr m_ptrOptCmdApi; //< 控制服务接口
|
||||
|
||||
SFbdModKey m_stModKey; //< 模块标识
|
||||
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
#include "AVG.h"
|
||||
#include "pub_utility_api/TimeUtil.h"
|
||||
|
||||
using namespace iot_public;
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
namespace app_fbd
|
||||
{
|
||||
|
||||
CAVG::CAVG()
|
||||
:m_bIngoreInvalidValue(true),
|
||||
m_nCalcPeriod(900),
|
||||
m_dSum(0.0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CAVG::~CAVG()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int CAVG::init(const SBaseCalcParam &stParam)
|
||||
{
|
||||
m_bIngoreInvalidValue = stParam.bIngoreInvalidValue;
|
||||
m_nCalcPeriod = stParam.nCalcPeriod;
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CAVG::calculate(const SFbdNumericValue &stInput,SFbdNumericValue &stOutput)
|
||||
{
|
||||
int64 lCurTime = getMonotonicMsec();
|
||||
|
||||
if(m_bIngoreInvalidValue)
|
||||
{
|
||||
if(isValidOfStatus(stInput.m_nStatus))
|
||||
{
|
||||
insertValue(lCurTime,stInput.m_dValue); //只有有效值参与计算
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
insertValue(lCurTime,stInput.m_dValue); //忽略状态
|
||||
}
|
||||
|
||||
size_t nIdx = 0;
|
||||
while(nIdx < m_dequeTime.size())
|
||||
{
|
||||
if(lCurTime - m_dequeTime[nIdx] > m_nCalcPeriod * MSEC_PER_SEC)
|
||||
{
|
||||
m_dSum -= m_dequeValue[nIdx];
|
||||
nIdx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break; //碰到未超时的跳出
|
||||
}
|
||||
}
|
||||
|
||||
//删除超时的部分
|
||||
for(size_t i = 0; i < nIdx; i++)
|
||||
{
|
||||
m_dequeTime.pop_front();
|
||||
m_dequeValue.pop_front();
|
||||
}
|
||||
|
||||
//求平均值
|
||||
if(m_dequeValue.empty())
|
||||
{
|
||||
stOutput.m_dValue = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
stOutput.m_dValue = m_dSum / m_dequeValue.size();
|
||||
}
|
||||
|
||||
stOutput.m_nStatus = CN_FBD_STATUS_Valid;
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CAVG::reset(const bool /*bMaster*/)
|
||||
{
|
||||
m_dequeValue.clear();
|
||||
m_dequeTime.clear();
|
||||
m_dSum = 0.0;
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
void CAVG::insertValue(const int64 &lCurTime, const double &dValue)
|
||||
{
|
||||
m_dequeValue.push_back(dValue);
|
||||
m_dequeTime.push_back(lCurTime);
|
||||
|
||||
m_dSum += dValue;
|
||||
}
|
||||
|
||||
|
||||
} //app_fbd
|
||||
} //iot_app
|
||||
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "BaseCalcInterface.h"
|
||||
#include <deque>
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
namespace app_fbd
|
||||
{
|
||||
class CAVG : public CBaseCalcInterface
|
||||
{
|
||||
public:
|
||||
CAVG();
|
||||
virtual ~CAVG();
|
||||
|
||||
virtual int init(const SBaseCalcParam &stParam);
|
||||
virtual int calculate(const SFbdNumericValue &stInput,SFbdNumericValue &stOutput);
|
||||
virtual int reset( const bool bMaster );
|
||||
|
||||
private:
|
||||
void insertValue(const int64 &lCurTime, const double &dValue);
|
||||
|
||||
private:
|
||||
bool m_bIngoreInvalidValue; //忽略无效值
|
||||
int m_nCalcPeriod; //滑窗计算周期,单位秒
|
||||
double m_dSum; //所有数据之和
|
||||
|
||||
std::deque<int64> m_dequeTime; //用来存储时间,判断数据是否过期,与m_dequeValue一一对应
|
||||
std::deque<double> m_dequeValue; //用来存储输入值
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<CAVG> CAVGPtr;
|
||||
|
||||
} //app_fbd
|
||||
} //iot_app
|
||||
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "app_fbd/fbd_common/BaseModule.h"
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
namespace app_fbd
|
||||
{
|
||||
|
||||
typedef struct _SBaseCalcParam
|
||||
{
|
||||
bool bIngoreInvalidValue; //忽略无效值
|
||||
int nCalcPeriod; //滑窗计算周期,单位秒
|
||||
}SBaseCalcParam,*PSBaseCalcParam;
|
||||
|
||||
class CBaseCalcInterface
|
||||
{
|
||||
public:
|
||||
virtual ~CBaseCalcInterface() = default;
|
||||
|
||||
virtual int init(const SBaseCalcParam &stParam) = 0;
|
||||
virtual int calculate(const SFbdNumericValue &stInput,SFbdNumericValue &stOutput) = 0;
|
||||
virtual int reset( const bool bMaster ) = 0;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<CBaseCalcInterface> CBaseCalcInterfacePtr;
|
||||
|
||||
} //app_fbd
|
||||
} //iot_app
|
||||
@ -0,0 +1,176 @@
|
||||
/**
|
||||
@file AntiShake.cpp
|
||||
@brief 延时输出模块
|
||||
@author 曹顶法
|
||||
*/
|
||||
|
||||
#include "boost/make_shared.hpp"
|
||||
|
||||
#include "BasePeriodCalc.h"
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "pub_utility_api/TimeUtil.h"
|
||||
#include "AVG.h"
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
namespace app_fbd
|
||||
{
|
||||
|
||||
CBasePeriodCalc::CBasePeriodCalc()
|
||||
: m_eCalcMode(CalcMode_Min),
|
||||
m_bFirstOutput(true),
|
||||
m_ptrCalc(NULL),
|
||||
m_ptrDiagData( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CBasePeriodCalc::~CBasePeriodCalc()
|
||||
{
|
||||
clean();
|
||||
m_ptrCalc.reset();
|
||||
m_ptrDiagData.reset();
|
||||
}
|
||||
|
||||
|
||||
int CBasePeriodCalc::init( const SFbdModKey &stModuleKey, const std::string & )
|
||||
{
|
||||
m_stModKey = stModuleKey;
|
||||
|
||||
m_ptrDiagData = getFbdDiagDataApi();
|
||||
if ( m_ptrDiagData == nullptr )
|
||||
{
|
||||
LOGERROR( "获取Diagram数据接口单例失败" );
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
//1.获取输入、输出参数
|
||||
if ( iotSuccess != m_ptrDiagData->getValKeyByModInput( stModuleKey, 1, m_stInKey1 ) ||
|
||||
iotSuccess != m_ptrDiagData->getValKeyByModOutput( stModuleKey, 1, m_stOutputValueKey ) ||
|
||||
iotSuccess != m_ptrDiagData->getValKeyByModOutput( stModuleKey, 2, m_stOutputChangedKey ))
|
||||
{
|
||||
LOGERROR( "获取模块[%s]的输入输出参数失败", stModuleKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
//2.获取属性参数
|
||||
std::string strCalcPeriod; //滑窗周期
|
||||
std::string strCalcMode; //计算模式
|
||||
std::string strIngoreInvalideValue; //忽略无效值
|
||||
|
||||
if (iotSuccess != m_ptrDiagData->getModProperty(stModuleKey,"CalcPeriod",strCalcPeriod) ||
|
||||
iotSuccess != m_ptrDiagData->getModProperty(stModuleKey,"CalcMode",strCalcMode) ||
|
||||
iotSuccess != m_ptrDiagData->getModProperty(stModuleKey,"IngoreInvalidValue",strIngoreInvalideValue) )
|
||||
{
|
||||
LOGERROR( "获取模块[%s]的属性参数失败", stModuleKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
boost::algorithm::trim(strCalcPeriod);
|
||||
boost::algorithm::trim(strCalcMode);
|
||||
boost::algorithm::trim(strIngoreInvalideValue);
|
||||
|
||||
m_stBaseParam.nCalcPeriod = boost::lexical_cast<int>(strCalcPeriod);
|
||||
m_stBaseParam.bIngoreInvalidValue = boost::lexical_cast<int>(strIngoreInvalideValue) != 0;
|
||||
int nCalcMode = boost::lexical_cast<int>(strCalcMode);
|
||||
if(nCalcMode <= CalcMode_Min || nCalcMode >= CalcMode_Max)
|
||||
{
|
||||
LOGERROR( "转换模块[%s]的属性参数失败", stModuleKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
m_eCalcMode = (CalcMode)nCalcMode;
|
||||
}
|
||||
catch ( const std::exception &e )
|
||||
{
|
||||
LOGERROR( "模块[%s]参数格式非法,Err:\n%s", m_stModKey.toString().c_str(), e.what());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
//创建计算实例
|
||||
if(iotSuccess != createCalcInstance())
|
||||
{
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
LOGINFO( "[%s]加载成功", m_stModKey.toString().c_str());
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CBasePeriodCalc::calculate()
|
||||
{
|
||||
SFbdNumericValue stInput( 0, CN_FBD_STATUS_Invalid );
|
||||
SFbdNumericValue stOutputValue( 0, CN_FBD_STATUS_Invalid );
|
||||
SFbdNumericValue stOutputChanged( 0, CN_FBD_STATUS_Valid );
|
||||
|
||||
//< 获取输入参数值和状态
|
||||
if ( iotSuccess != m_ptrDiagData->getNumericValByKey(m_stInKey1, stInput) )
|
||||
{
|
||||
LOGERROR( "获取模块[%s]的输入参数失败", m_stModKey.toString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ptrCalc->calculate(stInput,stOutputValue);
|
||||
}
|
||||
|
||||
if(m_stOutputValue != stOutputValue || m_bFirstOutput)
|
||||
{
|
||||
//第一次输出,或者值发生变化,则触发是否变化
|
||||
stOutputChanged.m_dValue = 1;
|
||||
m_ptrDiagData->setNumericValByKey(m_stOutputValueKey,stOutputValue);
|
||||
|
||||
m_bFirstOutput = false;
|
||||
m_stOutputValue = stOutputValue;
|
||||
}
|
||||
|
||||
m_ptrDiagData->setNumericValByKey(m_stOutputChangedKey,stOutputChanged);
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CBasePeriodCalc::reset( const bool bMaster )
|
||||
{
|
||||
m_bFirstOutput = true;
|
||||
if(m_ptrCalc != NULL)
|
||||
{
|
||||
m_ptrCalc->reset(bMaster);
|
||||
}
|
||||
|
||||
SFbdNumericValue stOutput( 0, CN_FBD_STATUS_Invalid );
|
||||
m_ptrDiagData->setNumericValByKey( m_stOutputValueKey, stOutput );
|
||||
m_ptrDiagData->setNumericValByKey( m_stOutputChangedKey, stOutput );
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
|
||||
int CBasePeriodCalc::clean()
|
||||
{
|
||||
return reset( false );
|
||||
}
|
||||
|
||||
boost::shared_ptr<CBasePeriodCalc> CBasePeriodCalc::create()
|
||||
{
|
||||
return boost::make_shared<CBasePeriodCalc>();
|
||||
}
|
||||
|
||||
int CBasePeriodCalc::createCalcInstance()
|
||||
{
|
||||
if(m_eCalcMode == CalcMode_AVG)
|
||||
{
|
||||
m_ptrCalc = boost::make_shared<CAVG>();
|
||||
}
|
||||
|
||||
if(m_ptrCalc != NULL && iotSuccess == m_ptrCalc->init(m_stBaseParam))
|
||||
{
|
||||
LOGINFO("模块[%s]创建计算类成功,mode=%d",m_stModKey.toString().c_str(),m_eCalcMode);
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
LOGERROR("模块[%s]创建计算类失败,mode=%d",m_stModKey.toString().c_str(),m_eCalcMode);
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
} //< namespace app_fbd
|
||||
} //< namespace iot_app
|
||||
@ -0,0 +1,68 @@
|
||||
/**
|
||||
@file AntiShake.h
|
||||
@brief 延时输出模块
|
||||
@author 曹顶法
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boost/dll/alias.hpp"
|
||||
#include "app_fbd/fbd_common/BaseModule.h"
|
||||
#include "app_fbd/fbd_common/FbdDiagDataApi.h"
|
||||
#include "BaseCalcInterface.h"
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
namespace app_fbd
|
||||
{
|
||||
|
||||
enum CalcMode{
|
||||
CalcMode_Min = -1, //无效值,用来判断枚举下限
|
||||
CalcMode_AVG = 0, //平均值
|
||||
CalcMode_Max //枚举最大值,用来判断枚举上限
|
||||
};
|
||||
|
||||
/* @brief 延迟输出模块,实现:当某值持续规定时间后输出,如果在时间内又发生了变化,重新计时 */
|
||||
class CBasePeriodCalc final : public CBaseModule
|
||||
{
|
||||
public:
|
||||
CBasePeriodCalc();
|
||||
~CBasePeriodCalc() override;
|
||||
|
||||
int init( const SFbdModKey &stModuleKey, const std::string &strExtraParam ) override;
|
||||
|
||||
int calculate() override;
|
||||
|
||||
int reset( const bool bMaster ) override;
|
||||
|
||||
int clean() override;
|
||||
|
||||
// Factory method
|
||||
static boost::shared_ptr<CBasePeriodCalc> create();
|
||||
|
||||
private:
|
||||
//创建计算类
|
||||
int createCalcInstance();
|
||||
|
||||
private:
|
||||
CalcMode m_eCalcMode; //计算方式
|
||||
bool m_bFirstOutput; //是否第一次输出,用来防止计算结果与默认值一致时无法输出的情况
|
||||
SBaseCalcParam m_stBaseParam; //计算相关参数
|
||||
|
||||
CBaseCalcInterfacePtr m_ptrCalc; //计算实例
|
||||
CFbdDiagDataApiPtr m_ptrDiagData; //< Diagram数据接口
|
||||
|
||||
SFbdValueKey m_stInKey1; //< 输入1 key 输入值
|
||||
SFbdValueKey m_stOutputValueKey; //< 输出参数
|
||||
SFbdValueKey m_stOutputChangedKey; //< 输出是否变化
|
||||
SFbdNumericValue m_stOutputValue; //输出值
|
||||
|
||||
SFbdModKey m_stModKey; //< 模块标识
|
||||
};
|
||||
|
||||
BOOST_DLL_ALIAS(
|
||||
CBasePeriodCalc::create, // 要导出的函数
|
||||
create_plugin // 将导出函数重命名,最终调用者访问此函数名
|
||||
)
|
||||
|
||||
} //< namespace app_fbd
|
||||
} //< namespace iot_app
|
||||
@ -0,0 +1,35 @@
|
||||
QT -= core gui
|
||||
CONFIG -= qt
|
||||
|
||||
TEMPLATE = lib
|
||||
TARGET = base_period_calc
|
||||
|
||||
# Input
|
||||
HEADERS += \
|
||||
BasePeriodCalc.h \
|
||||
AVG.h \
|
||||
BaseCalcInterface.h
|
||||
|
||||
SOURCES += \
|
||||
BasePeriodCalc.cpp \
|
||||
AVG.cpp
|
||||
|
||||
|
||||
LIBS += -lboost_system -lboost_chrono
|
||||
LIBS += -lpub_logger_api -llog4cplus -lnet_msg_bus_api -lrdb_api -lfbd_common
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
COMMON_PRI=$$PWD/../../../../common.pri
|
||||
exists($$COMMON_PRI) {
|
||||
include($$COMMON_PRI)
|
||||
}else {
|
||||
error("FATAL error: can not find common.pri")
|
||||
}
|
||||
|
||||
#为了统一将fbd_module下所有dll生成到规定目录
|
||||
FBD_MODULE_PRI=$$PWD/../fbd_module.pri
|
||||
exists($$FBD_MODULE_PRI) {
|
||||
include($$FBD_MODULE_PRI)
|
||||
}else {
|
||||
error("FATAL error: can not find fbd_module.pri")
|
||||
}
|
||||
@ -45,6 +45,13 @@ int CDoCtrl::init( const SFbdModKey &stModuleKey, const std::string & )
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
m_ptrOptCmdApi = getFbdDiagOptCmdApi();
|
||||
if( m_ptrOptCmdApi == nullptr )
|
||||
{
|
||||
LOGERROR( "获取控制反馈接口单例失败" );
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
//1.解析配置
|
||||
if ( iotSuccess != initCtrlParam())
|
||||
{
|
||||
@ -84,30 +91,12 @@ int CDoCtrl::calculate()
|
||||
{
|
||||
//< 接收消息总线消息
|
||||
{
|
||||
if ( nullptr == m_pMbComm )
|
||||
while(true)
|
||||
{
|
||||
LOGERROR( "通讯器指针为空,非预期,检查程序!" );
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
iot_net::CMbMessage objMsg;
|
||||
while ( m_pMbComm->recvMsg( objMsg, 0 ))
|
||||
{
|
||||
COptCtrlReply objParse;
|
||||
SOptCtrlReplyPtr ptrOptRep = boost::make_shared<SOptCtrlReply>();
|
||||
|
||||
const std::string strMsg(( const char * ) objMsg.getDataPtr(), objMsg.getDataSize());
|
||||
if ( !objParse.parse( strMsg, *ptrOptRep ))
|
||||
SOptCtrlReplyPtr ptrOptRep = m_ptrOptCmdApi->getOptCtrlReply(m_stModKey.toString());
|
||||
if(ptrOptRep == NULL)
|
||||
{
|
||||
LOGERROR( "反馈命令解析失败" );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ptrOptRep->stHead.strInstName != m_stModKey.toString() ||
|
||||
ptrOptRep->stHead.strHostName != getFbdSysInfoApi()->getCurrentRunAppInfo().strLocalNodeName )
|
||||
{
|
||||
//< 非本进程的反馈,丢弃
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
const auto itMap = m_mapCmdOfPnt.find( ptrOptRep->stHead.strKeyIdTag );
|
||||
@ -227,16 +216,18 @@ int CDoCtrl::reset( const bool bMaster )
|
||||
int nRet = iotSuccess;
|
||||
if ( bMaster )
|
||||
{
|
||||
if ( nullptr == m_pMbComm )
|
||||
m_pMbComm = new iot_net::CMbCommunicator;
|
||||
|
||||
//< 必须订阅所有专业,因为可能控制其他专业的测点
|
||||
m_pMbComm->addSub( 0, CH_OPT_TO_HMI_OPTCMD_UP );
|
||||
if(m_ptrOptCmdApi != NULL)
|
||||
{
|
||||
m_ptrOptCmdApi->subOptCtrlReplyTopic(m_stModKey.toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_pMbComm;
|
||||
m_pMbComm = nullptr;
|
||||
if(m_ptrOptCmdApi != NULL)
|
||||
{
|
||||
m_ptrOptCmdApi->unsubOptCtrlReplyTopic(m_stModKey.toString());
|
||||
}
|
||||
}
|
||||
|
||||
m_mapCmdOfPnt.clear(); //< 清空命令
|
||||
@ -249,11 +240,9 @@ int CDoCtrl::clean()
|
||||
{
|
||||
int nRet = reset( false );
|
||||
|
||||
m_ptrOptCmdApi.reset();
|
||||
m_ptrDiagData.reset();
|
||||
|
||||
delete m_pMbComm;
|
||||
m_pMbComm = nullptr;
|
||||
|
||||
return nRet;
|
||||
}
|
||||
|
||||
@ -358,7 +347,7 @@ void CDoCtrl::sendCtrlCmd( SCtrlCmd &stCmd, const ECmdState eSuccessState, const
|
||||
stReq.stHead.nAppID = stRunAppInfo.nAppId;
|
||||
stReq.stHead.strHostName = stRunAppInfo.strLocalNodeName;
|
||||
stReq.stHead.strInstName = m_stModKey.toString();
|
||||
stReq.stHead.strCommName = m_pMbComm->getName();
|
||||
stReq.stHead.strCommName = m_ptrOptCmdApi->getMbCommName();
|
||||
stReq.stHead.nUserID = 1; //< 用户ID,默认1 管理员
|
||||
stReq.stHead.nUserGroupID = 1; //< 用户组ID,默认1 管理员
|
||||
stReq.stHead.nOptTime = stCmd.lSendUtcMsec;
|
||||
@ -369,8 +358,7 @@ void CDoCtrl::sendCtrlCmd( SCtrlCmd &stCmd, const ECmdState eSuccessState, const
|
||||
stCtrlReq.bIsDeviceOccupy = true;
|
||||
stReq.vecOptCtrlQueue.push_back( stCtrlReq );
|
||||
|
||||
COptCtrlRequest objGen;
|
||||
stCmd.strLastSendJsonReq = objGen.generate( stReq );
|
||||
stCmd.strLastSendJsonReq = COptCtrlRequest::generate( stReq );
|
||||
if ( stCmd.strLastSendJsonReq.empty())
|
||||
{
|
||||
LOGERROR( "生成控制报文失败。KeyIdTag=[%s]", stCtrlReq.strKeyIdTag.c_str());
|
||||
@ -380,7 +368,7 @@ void CDoCtrl::sendCtrlCmd( SCtrlCmd &stCmd, const ECmdState eSuccessState, const
|
||||
|
||||
iot_net::CMbMessage objMsg( stCmd.strLastSendJsonReq, stCmd.nAppId,
|
||||
CH_HMI_TO_OPT_OPTCMD_DOWN, MT_OPT_AUTO_CTRL_DOWN );
|
||||
if ( m_pMbComm->sendMsgToDomain( objMsg, stCmd.nDstDomainId ))
|
||||
if ( m_ptrOptCmdApi->sendOptCtrReqToDomain(objMsg,stCmd.nDstDomainId) )
|
||||
{
|
||||
stCmd.setResult( true, "发送控制命令成功", eSuccessState );
|
||||
LOGINFO( "发送控制命令到域[%d],应用[%d]成功,KeyIdTag=[%s],控制目标值[%lf]",
|
||||
@ -421,9 +409,8 @@ void CDoCtrl::waitCtrlRep( SCmdOfOnePnt &stCmdOfOnePnt, const ECmdState eSuccess
|
||||
|
||||
if ( ptrRep->stHead.nOptTime != stCurrentCmd.lSendUtcMsec )
|
||||
{
|
||||
COptCtrlReply objParse;
|
||||
LOGINFO( "时间不一致,忽略,收到的回复消息如下:\n%s",
|
||||
objParse.generate( *ptrRep ).c_str());
|
||||
COptCtrlReply::generate( *ptrRep ).c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include "operate_server_api/JsonOptCommand.h"
|
||||
#include "app_fbd/fbd_common/BaseModule.h"
|
||||
#include "app_fbd/fbd_common/FbdDiagDataApi.h"
|
||||
#include "app_fbd/fbd_common/FbdDiagOptCmdApi.h"
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
@ -140,7 +141,8 @@ private:
|
||||
int parseKeyIdTag( const std::string &strKeyIdTag, SCtrlCmd &stCtrlCmd );
|
||||
|
||||
private:
|
||||
CFbdDiagDataApiPtr m_ptrDiagData; //< Diagram数据接口
|
||||
CFbdDiagDataApiPtr m_ptrDiagData; //< Diagram数据接口
|
||||
CFbdDiagOptCmdApiPtr m_ptrOptCmdApi; //< 控制服务接口
|
||||
|
||||
iot_net::CMbCommunicator *m_pMbComm{nullptr}; //< 消息总线通信器
|
||||
|
||||
|
||||
@ -16,5 +16,6 @@ SUBDIRS += anti_shake \
|
||||
mux \
|
||||
pnt_input \
|
||||
pnt_output \
|
||||
|
||||
|
||||
global_output \
|
||||
global_input \
|
||||
base_period_calc
|
||||
|
||||
@ -0,0 +1,163 @@
|
||||
/**
|
||||
@file GlobalInput.cpp
|
||||
@brief 全局变量输入类
|
||||
@author 曹顶法
|
||||
*/
|
||||
|
||||
#include "GlobalInput.h"
|
||||
#include "boost/make_shared.hpp"
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "pub_utility_api/CharUtil.h"
|
||||
#include "pub_utility_api/TimeUtil.h"
|
||||
#include "fbd_designer/fbd_block/BlockDefine.h"
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
namespace app_fbd
|
||||
{
|
||||
|
||||
CGlobalInput::CGlobalInput()
|
||||
: m_nVarDataType(0),
|
||||
m_ptrDiagData( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
CGlobalInput::~CGlobalInput()
|
||||
{
|
||||
clean();
|
||||
m_ptrDiagData.reset();
|
||||
}
|
||||
|
||||
int CGlobalInput::init( const SFbdModKey &stModuleKey, const std::string &strExtraParam )
|
||||
{
|
||||
boost::ignore_unused_variable_warning(strExtraParam);
|
||||
|
||||
m_stModKey = stModuleKey;
|
||||
m_ptrDiagData = getFbdDiagDataApi();
|
||||
if ( m_ptrDiagData == nullptr )
|
||||
{
|
||||
LOGERROR( "获取Diagram数据接口单例失败" );
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
std::string strVarDataType;
|
||||
|
||||
//< 1.先获取参数信息,获取数据类型和是否启用了使能引脚
|
||||
if(iotSuccess != m_ptrDiagData->getModProperty(m_stModKey,"VarName",m_strVarName) ||
|
||||
iotSuccess != m_ptrDiagData->getModProperty(m_stModKey,"VarDataType",strVarDataType))
|
||||
{
|
||||
LOGERROR( "获取模块[%s]属性失败", m_stModKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
if(m_strVarName.empty())
|
||||
{
|
||||
LOGERROR( "模块[%s]变量名为空", m_stModKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_nVarDataType = boost::lexical_cast<int>(strVarDataType);
|
||||
}
|
||||
catch ( const std::exception &e )
|
||||
{
|
||||
LOGERROR( "模块[%s]参数格式非法,Err:\n%s", m_stModKey.toString().c_str(), e.what());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
if(m_nVarDataType != E_PORTDATA_BOOL && m_nVarDataType != E_PORTDATA_INT &&
|
||||
m_nVarDataType != E_PORTDATA_FLOAT && m_nVarDataType != E_PORTDATA_STRING)
|
||||
{
|
||||
LOGERROR("模块[%s]数据类型非法,仅支持数值型和字符串类型", m_stModKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
//< 2.获取输出参数
|
||||
if ( iotSuccess != m_ptrDiagData->getValKeyByModOutput( stModuleKey, 1, m_stOutKeyValue ) )
|
||||
{
|
||||
LOGERROR( "获取模块[%s]的输出参数失败", stModuleKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
LOGINFO( "[%s]加载成功", m_stModKey.toString().c_str());
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
|
||||
int CGlobalInput::calculate()
|
||||
{
|
||||
switch (m_nVarDataType)
|
||||
{
|
||||
case E_PORTDATA_INT:
|
||||
case E_PORTDATA_FLOAT:
|
||||
case E_PORTDATA_BOOL:
|
||||
return calcNumericValue();
|
||||
case E_PORTDATA_STRING:
|
||||
return calcStringValue();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CGlobalInput::calcNumericValue()
|
||||
{
|
||||
//失败默认输出无效值0
|
||||
SFbdNumericValue stOutput( 0, CN_FBD_STATUS_Invalid );
|
||||
if(iotSuccess != m_ptrDiagData->getGlobalNumericValByKey(m_strVarName,stOutput))
|
||||
{
|
||||
//< 出错则将值设置为无效状态
|
||||
LOGERROR( "获取模块[%s]输入参数[%s]值失败", m_stModKey.toString().c_str(),
|
||||
m_strVarName.c_str());
|
||||
}
|
||||
|
||||
if(iotSuccess != m_ptrDiagData->setNumericValByKey(m_stOutKeyValue,stOutput))
|
||||
{
|
||||
LOGERROR( "设置模块[%s]的设置输出[%s]值失败", m_stModKey.toString().c_str(),
|
||||
m_stOutKeyValue.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CGlobalInput::calcStringValue()
|
||||
{
|
||||
//失败默认输出无效值 空字符串
|
||||
SFbdStringValue stOutput( "", CN_FBD_STATUS_Invalid );
|
||||
if(iotSuccess != m_ptrDiagData->getGlobalStringValByKey(m_strVarName,stOutput))
|
||||
{
|
||||
//< 出错则将值设置为无效状态
|
||||
LOGERROR( "获取模块[%s]输入参数[%s]值失败", m_stModKey.toString().c_str(),
|
||||
m_strVarName.c_str());
|
||||
}
|
||||
|
||||
if(iotSuccess != m_ptrDiagData->setStringValByKey(m_stOutKeyValue,stOutput))
|
||||
{
|
||||
LOGERROR( "设置模块[%s]的设置输出[%s]值失败", m_stModKey.toString().c_str(),
|
||||
m_stOutKeyValue.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CGlobalInput::reset( const bool /*bMaster*/ )
|
||||
{
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CGlobalInput::clean()
|
||||
{
|
||||
return reset( false );
|
||||
}
|
||||
|
||||
boost::shared_ptr<CGlobalInput> CGlobalInput::create()
|
||||
{
|
||||
return boost::make_shared<CGlobalInput>();
|
||||
}
|
||||
|
||||
} //< namespace app_fbd
|
||||
} //< namespace iot_app
|
||||
@ -0,0 +1,64 @@
|
||||
/**
|
||||
@file GlobalInput.h
|
||||
@brief 全局变量输入类
|
||||
@author 曹顶法
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boost/dll/alias.hpp"
|
||||
#include "app_fbd/fbd_common/BaseModule.h"
|
||||
#include "app_fbd/fbd_common/FbdDiagDataApi.h"
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
namespace app_fbd
|
||||
{
|
||||
|
||||
/* @brief 全局变量输入类 */
|
||||
class CGlobalInput final : public CBaseModule
|
||||
{
|
||||
public:
|
||||
CGlobalInput();
|
||||
virtual ~CGlobalInput() override;
|
||||
|
||||
int init( const SFbdModKey &stModuleKey, const std::string &strExtraParam ) override;
|
||||
|
||||
int calculate() override;
|
||||
|
||||
int reset( const bool bMaster ) override;
|
||||
|
||||
int clean() override;
|
||||
|
||||
// Factory method
|
||||
static boost::shared_ptr<CGlobalInput> create();
|
||||
|
||||
private:
|
||||
/**
|
||||
@brief 处理数值类型
|
||||
@return 成功返回iotSuccess,失败返回错误码
|
||||
*/
|
||||
int calcNumericValue();
|
||||
|
||||
/**
|
||||
@brief 处理字符串类型
|
||||
@return 成功返回iotSuccess,失败返回错误码
|
||||
*/
|
||||
int calcStringValue();
|
||||
|
||||
private:
|
||||
std::string m_strVarName; //< 变量名
|
||||
int m_nVarDataType; //< 变量数据类型
|
||||
|
||||
CFbdDiagDataApiPtr m_ptrDiagData; //< Diagram数据接口
|
||||
|
||||
SFbdModKey m_stModKey; //< 模块标识
|
||||
SFbdValueKey m_stOutKeyValue; //< 输出参数1, 值
|
||||
};
|
||||
|
||||
BOOST_DLL_ALIAS(
|
||||
CGlobalInput::create, // 要导出的函数
|
||||
create_plugin // 将导出函数重命名,最终调用者访问此函数名
|
||||
)
|
||||
|
||||
} //< namespace app_fbd
|
||||
} //< namespace iot_app
|
||||
@ -0,0 +1,35 @@
|
||||
QT -= core gui
|
||||
CONFIG -= qt
|
||||
|
||||
TEMPLATE = lib
|
||||
TARGET = global_input
|
||||
|
||||
# Input
|
||||
HEADERS += \
|
||||
GlobalInput.h
|
||||
|
||||
SOURCES += \
|
||||
GlobalInput.cpp
|
||||
|
||||
|
||||
LIBS += -lboost_system -lboost_chrono
|
||||
LIBS += -lpub_logger_api -llog4cplus -lfbd_common
|
||||
|
||||
include($$PWD/../../../../idl_files/idl_files.pri)
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
COMMON_PRI=$$PWD/../../../../common.pri
|
||||
exists($$COMMON_PRI) {
|
||||
include($$COMMON_PRI)
|
||||
}else {
|
||||
error("FATAL error: can not find common.pri")
|
||||
}
|
||||
|
||||
|
||||
#为了统一将fbd_module下所有dll生成到规定目录
|
||||
FBD_MODULE_PRI=$$PWD/../fbd_module.pri
|
||||
exists($$FBD_MODULE_PRI) {
|
||||
include($$FBD_MODULE_PRI)
|
||||
}else {
|
||||
error("FATAL error: can not find fbd_module.pri")
|
||||
}
|
||||
@ -0,0 +1,303 @@
|
||||
/**
|
||||
@file GlobalOutput.cpp
|
||||
@brief 全局输出类
|
||||
@author 曹顶法
|
||||
*/
|
||||
|
||||
#include "GlobalOutput.h"
|
||||
#include "boost/make_shared.hpp"
|
||||
#include "pub_logger_api/logger.h"
|
||||
#include "pub_utility_api/CharUtil.h"
|
||||
#include "pub_utility_api/TimeUtil.h"
|
||||
#include "fbd_designer/fbd_block/BlockDefine.h"
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
namespace app_fbd
|
||||
{
|
||||
|
||||
CGlobalOutput::CGlobalOutput()
|
||||
: m_nVarDataType(0),
|
||||
m_bHasEnableInput(false),
|
||||
m_bIsRegist(false),
|
||||
m_ptrDiagData( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
CGlobalOutput::~CGlobalOutput()
|
||||
{
|
||||
clean();
|
||||
m_ptrDiagData.reset();
|
||||
}
|
||||
|
||||
int CGlobalOutput::init( const SFbdModKey &stModuleKey, const std::string &strExtraParam )
|
||||
{
|
||||
boost::ignore_unused_variable_warning(strExtraParam);
|
||||
|
||||
m_stModKey = stModuleKey;
|
||||
m_ptrDiagData = getFbdDiagDataApi();
|
||||
if ( m_ptrDiagData == nullptr )
|
||||
{
|
||||
LOGERROR( "获取Diagram数据接口单例失败" );
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
std::string strHasEnableInput;
|
||||
std::string strVarDataType;
|
||||
|
||||
//< 1.先获取参数信息,获取数据类型和是否启用了使能引脚
|
||||
if(iotSuccess != m_ptrDiagData->getModProperty(m_stModKey,"VarName",m_strVarName) ||
|
||||
iotSuccess != m_ptrDiagData->getModProperty(m_stModKey,"HasEnableInput",strHasEnableInput) ||
|
||||
iotSuccess != m_ptrDiagData->getModProperty(m_stModKey,"VarDataType",strVarDataType))
|
||||
{
|
||||
LOGERROR( "获取模块[%s]属性失败", m_stModKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
if(m_strVarName.empty())
|
||||
{
|
||||
LOGERROR( "模块[%s]变量名为空", m_stModKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_bHasEnableInput = boost::lexical_cast<int>(strHasEnableInput) != 0;
|
||||
m_nVarDataType = boost::lexical_cast<int>(strVarDataType);
|
||||
}
|
||||
catch ( const std::exception &e )
|
||||
{
|
||||
LOGERROR( "模块[%s]参数格式非法,Err:\n%s", m_stModKey.toString().c_str(), e.what());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
if(m_nVarDataType != E_PORTDATA_BOOL && m_nVarDataType != E_PORTDATA_INT &&
|
||||
m_nVarDataType != E_PORTDATA_FLOAT && m_nVarDataType != E_PORTDATA_STRING)
|
||||
{
|
||||
LOGERROR("模块[%s]数据类型非法,仅支持数值型和字符串类型", m_stModKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
//< 2.获取输入、输出参数
|
||||
if ( iotSuccess != m_ptrDiagData->getValKeyByModInput( stModuleKey, 1, m_stInKeyValue ) ||
|
||||
(m_bHasEnableInput && (iotSuccess != m_ptrDiagData->getValKeyByModInput(stModuleKey, 2, m_stInKeyEnable))) )
|
||||
{
|
||||
LOGERROR( "获取模块[%s]的输入输出参数失败", stModuleKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
//< 3.查看变量是否已经存在,防止不同的全局变量重名,暂时只是日志提醒
|
||||
if(!registGlobalVariable())
|
||||
{
|
||||
LOGERROR("模块[%s]注册全局变量[%s]失败", stModuleKey.toString().c_str(),m_strVarName.c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
LOGINFO( "[%s]加载成功", m_stModKey.toString().c_str());
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
|
||||
int CGlobalOutput::calculate()
|
||||
{
|
||||
if(!isEnableOutput())
|
||||
{
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
switch (m_nVarDataType)
|
||||
{
|
||||
case E_PORTDATA_INT:
|
||||
case E_PORTDATA_FLOAT:
|
||||
case E_PORTDATA_BOOL:
|
||||
return calcNumericValue();
|
||||
case E_PORTDATA_STRING:
|
||||
return calcStringValue();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
bool CGlobalOutput::isEnableOutput()
|
||||
{
|
||||
if(!m_bHasEnableInput)
|
||||
{
|
||||
return true; //没有使能引脚,默认输出
|
||||
}
|
||||
|
||||
SFbdNumericValue stInValEnable;
|
||||
if ( iotSuccess != m_ptrDiagData->getNumericValByKey( m_stInKeyEnable, stInValEnable ))
|
||||
{
|
||||
LOGERROR( "获取模块[%s]的输入 使能 的值失败", m_stModKey.toString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!isValidOfStatus(stInValEnable.m_nStatus))
|
||||
{
|
||||
return false; //< 状态无效,禁用输出
|
||||
}
|
||||
|
||||
bool bEnableOutput = (0 != static_cast<int>(stInValEnable.m_dValue));
|
||||
|
||||
return bEnableOutput;
|
||||
}
|
||||
|
||||
bool CGlobalOutput::registGlobalVariable()
|
||||
{
|
||||
int nRegResult = iotSuccess;
|
||||
if(m_nVarDataType == E_PORTDATA_STRING) //前面做了类型合法性判断,此处不再精准判断
|
||||
{
|
||||
SFbdStringValue stInitValue( "", CN_FBD_STATUS_Invalid );
|
||||
nRegResult = m_ptrDiagData->regGlobalStringValByKey(m_strVarName,stInitValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SFbdNumericValue stInitValue( 0, CN_FBD_STATUS_Invalid );
|
||||
nRegResult = m_ptrDiagData->regGlobalNumericValByKey(m_strVarName,stInitValue);
|
||||
}
|
||||
|
||||
if(nRegResult == iotSuccess)
|
||||
{
|
||||
LOGINFO("模块[%s]的全局变量[%s]注册成功", m_stModKey.toString().c_str(),m_strVarName.c_str());
|
||||
m_bIsRegist = true;
|
||||
return true;
|
||||
}
|
||||
else if(nRegResult == iotFBDErr_GlobalVarAlreadyExist)
|
||||
{
|
||||
LOGWARN("模块[%s]的全局变量[%s]已经存在", m_stModKey.toString().c_str(),m_strVarName.c_str());
|
||||
//不设置m_bIsRegist为true,本着谁注册谁销毁的原则处理
|
||||
return true;
|
||||
}
|
||||
else if(nRegResult == iotFBDErr_GlobalVarTypeMismatch)
|
||||
{
|
||||
LOGERROR("模块[%s]的全局变量[%s]已经存在且数据类型不匹配", m_stModKey.toString().c_str(),m_strVarName.c_str());
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR("模块[%s]的全局变量[%s]注册失败", m_stModKey.toString().c_str(),m_strVarName.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CGlobalOutput::unregistGlobalVariable()
|
||||
{
|
||||
int nRegResult = iotSuccess;
|
||||
if(m_nVarDataType == E_PORTDATA_STRING) //前面做了类型合法性判断,此处不再精准判断
|
||||
{
|
||||
nRegResult = m_ptrDiagData->unregGlobalStringVar(m_strVarName);
|
||||
}
|
||||
else
|
||||
{
|
||||
nRegResult = m_ptrDiagData->unregGlobalNumericVar(m_strVarName);
|
||||
}
|
||||
|
||||
if(iotSuccess != nRegResult)
|
||||
{
|
||||
LOGERROR("模块[%s]的全局变量[%s]取消注册失败", m_stModKey.toString().c_str(),m_strVarName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bIsRegist = false;
|
||||
LOGINFO("模块[%s]的全局变量[%s]取消注册成功", m_stModKey.toString().c_str(),m_strVarName.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
int CGlobalOutput::calcNumericValue()
|
||||
{
|
||||
//使能,同时状态有效,则输出计算
|
||||
SFbdNumericValue stInput( 0, CN_FBD_STATUS_Invalid );
|
||||
if ( iotSuccess != m_ptrDiagData->getNumericValByKey( m_stInKeyValue, stInput ))
|
||||
{
|
||||
//< 出错则将值设置为无效状态
|
||||
LOGERROR( "获取模块[%s]输入参数[%s]值失败", m_stModKey.toString().c_str(),
|
||||
m_strVarName.c_str());
|
||||
}
|
||||
|
||||
if(iotSuccess != m_ptrDiagData->setGlobalNumericValByKey(m_strVarName,stInput))
|
||||
{
|
||||
LOGERROR( "设置模块[%s]的变量[%s]值失败", m_stModKey.toString().c_str(),
|
||||
m_strVarName.c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
int CGlobalOutput::calcStringValue()
|
||||
{
|
||||
//使能,同时状态有效,则输出计算
|
||||
SFbdStringValue stInput( "", CN_FBD_STATUS_Invalid );
|
||||
if ( iotSuccess != m_ptrDiagData->getStringValByKey( m_stInKeyValue, stInput ))
|
||||
{
|
||||
//< 出错则将值设置为无效状态
|
||||
LOGERROR( "获取模块[%s]输入参数[%s]值失败", m_stModKey.toString().c_str(),
|
||||
m_strVarName.c_str());
|
||||
}
|
||||
|
||||
if(iotSuccess != m_ptrDiagData->setGlobalStringValByKey(m_strVarName,stInput))
|
||||
{
|
||||
LOGERROR( "设置模块[%s]的变量[%s]值失败", m_stModKey.toString().c_str(),
|
||||
m_strVarName.c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
|
||||
int CGlobalOutput::reset( const bool /*bMaster*/ )
|
||||
{
|
||||
if(m_strVarName.empty() || m_ptrDiagData == nullptr)
|
||||
{
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
//主备切换时,暂时将值设置为无效值
|
||||
int nRet = iotSuccess;
|
||||
SFbdNumericValue stVal(0,CN_FBD_STATUS_Invalid);
|
||||
SFbdStringValue stStrVal("",CN_FBD_STATUS_Invalid);
|
||||
|
||||
switch (m_nVarDataType)
|
||||
{
|
||||
case E_PORTDATA_INT:
|
||||
case E_PORTDATA_FLOAT:
|
||||
case E_PORTDATA_BOOL:
|
||||
nRet = m_ptrDiagData->setGlobalNumericValByKey(m_strVarName,stVal);
|
||||
break;
|
||||
case E_PORTDATA_STRING:
|
||||
nRet = m_ptrDiagData->setGlobalStringValByKey(m_strVarName,stStrVal);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(nRet != iotSuccess)
|
||||
{
|
||||
LOGERROR("主备切换时设置模块[%s]的变量[%s]值失败", m_stModKey.toString().c_str(),
|
||||
m_strVarName.c_str());
|
||||
}
|
||||
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
|
||||
int CGlobalOutput::clean()
|
||||
{
|
||||
if(m_bIsRegist)
|
||||
{
|
||||
unregistGlobalVariable();
|
||||
}
|
||||
|
||||
return reset( false );
|
||||
}
|
||||
|
||||
boost::shared_ptr<CGlobalOutput> CGlobalOutput::create()
|
||||
{
|
||||
return boost::make_shared<CGlobalOutput>();
|
||||
}
|
||||
|
||||
} //< namespace app_fbd
|
||||
} //< namespace iot_app
|
||||
@ -0,0 +1,86 @@
|
||||
/**
|
||||
@file GlobalOutput.h
|
||||
@brief 全局变量输出类
|
||||
@author 曹顶法
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boost/dll/alias.hpp"
|
||||
#include "app_fbd/fbd_common/BaseModule.h"
|
||||
#include "app_fbd/fbd_common/FbdDiagDataApi.h"
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
namespace app_fbd
|
||||
{
|
||||
|
||||
/* @brief 全局变量输出类 */
|
||||
class CGlobalOutput final : public CBaseModule
|
||||
{
|
||||
public:
|
||||
CGlobalOutput();
|
||||
virtual ~CGlobalOutput() override;
|
||||
|
||||
int init( const SFbdModKey &stModuleKey, const std::string &strExtraParam ) override;
|
||||
|
||||
int calculate() override;
|
||||
|
||||
int reset( const bool bMaster ) override;
|
||||
|
||||
int clean() override;
|
||||
|
||||
// Factory method
|
||||
static boost::shared_ptr<CGlobalOutput> create();
|
||||
|
||||
private:
|
||||
/**
|
||||
@brief 是否允许输出
|
||||
@return 成功返回true,失败返回false
|
||||
*/
|
||||
bool isEnableOutput();
|
||||
|
||||
/**
|
||||
@brief 注册全局变量
|
||||
@return 成功返回true,失败返回false
|
||||
*/
|
||||
bool registGlobalVariable();
|
||||
|
||||
/**
|
||||
@brief 取消注册全局变量
|
||||
@return 成功返回true,失败返回false
|
||||
*/
|
||||
bool unregistGlobalVariable();
|
||||
|
||||
/**
|
||||
@brief 处理数值类型
|
||||
@return 成功返回iotSuccess,失败返回错误码
|
||||
*/
|
||||
int calcNumericValue();
|
||||
|
||||
/**
|
||||
@brief 处理字符串类型
|
||||
@return 成功返回iotSuccess,失败返回错误码
|
||||
*/
|
||||
int calcStringValue();
|
||||
|
||||
private:
|
||||
std::string m_strVarName; //< 变量名
|
||||
int m_nVarDataType; //< 变量数据类型
|
||||
bool m_bHasEnableInput; //< 是否启用了使能引脚,0:禁用,1:启用
|
||||
bool m_bIsRegist; //< 变量是否已经注册,用于识别是否需要取消注册
|
||||
|
||||
CFbdDiagDataApiPtr m_ptrDiagData; //< Diagram数据接口
|
||||
|
||||
SFbdModKey m_stModKey; //< 模块标识
|
||||
|
||||
SFbdValueKey m_stInKeyValue; //< 输入参数1, 值
|
||||
SFbdValueKey m_stInKeyEnable; //< 输入参数2, 是否使能
|
||||
};
|
||||
|
||||
BOOST_DLL_ALIAS(
|
||||
CGlobalOutput::create, // 要导出的函数
|
||||
create_plugin // 将导出函数重命名,最终调用者访问此函数名
|
||||
)
|
||||
|
||||
} //< namespace app_fbd
|
||||
} //< namespace iot_app
|
||||
@ -0,0 +1,35 @@
|
||||
QT -= core gui
|
||||
CONFIG -= qt
|
||||
|
||||
TEMPLATE = lib
|
||||
TARGET = global_output
|
||||
|
||||
# Input
|
||||
HEADERS += \
|
||||
GlobalOutput.h
|
||||
|
||||
SOURCES += \
|
||||
GlobalOutput.cpp
|
||||
|
||||
|
||||
LIBS += -lboost_system -lboost_chrono
|
||||
LIBS += -lpub_logger_api -llog4cplus -lfbd_common
|
||||
|
||||
include($$PWD/../../../../idl_files/idl_files.pri)
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
COMMON_PRI=$$PWD/../../../../common.pri
|
||||
exists($$COMMON_PRI) {
|
||||
include($$COMMON_PRI)
|
||||
}else {
|
||||
error("FATAL error: can not find common.pri")
|
||||
}
|
||||
|
||||
|
||||
#为了统一将fbd_module下所有dll生成到规定目录
|
||||
FBD_MODULE_PRI=$$PWD/../fbd_module.pri
|
||||
exists($$FBD_MODULE_PRI) {
|
||||
include($$FBD_MODULE_PRI)
|
||||
}else {
|
||||
error("FATAL error: can not find fbd_module.pri")
|
||||
}
|
||||
@ -54,7 +54,7 @@ int CAnd::calc( const std::vector<SFbdNumericValue> &vecInput,
|
||||
SFbdNumericValue &stOutput )
|
||||
{
|
||||
int nValue = static_cast<int>(vecInput[0].m_dValue);
|
||||
stOutput.m_nStatus = CN_FBD_STATUS_Valid;
|
||||
stOutput.m_nStatus = vecInput[0].m_nStatus;
|
||||
|
||||
for ( size_t i = 1; i < vecInput.size(); ++i )
|
||||
{
|
||||
|
||||
@ -45,7 +45,7 @@ int COr::calc( const std::vector<SFbdNumericValue> &vecInput,
|
||||
SFbdNumericValue &stOutput )
|
||||
{
|
||||
int nValue = static_cast<int>(vecInput[0].m_dValue);
|
||||
stOutput.m_nStatus = CN_FBD_STATUS_Valid;
|
||||
stOutput.m_nStatus = vecInput[0].m_nStatus;
|
||||
|
||||
for ( size_t i = 1; i < vecInput.size(); ++i )
|
||||
{
|
||||
|
||||
@ -32,6 +32,8 @@ CPntInput::~CPntInput()
|
||||
|
||||
int CPntInput::init( const SFbdModKey &stModuleKey, const std::string & )
|
||||
{
|
||||
m_strInputKeyId = "";
|
||||
m_strIsOutputKeyId = "";
|
||||
m_stModKey = stModuleKey;
|
||||
|
||||
m_ptrDiagData = getFbdDiagDataApi();
|
||||
@ -50,16 +52,25 @@ int CPntInput::init( const SFbdModKey &stModuleKey, const std::string & )
|
||||
|
||||
//< 获取参数
|
||||
{
|
||||
std::string strInputKeyId;
|
||||
if ( iotSuccess != m_ptrDiagData->getModProperty( stModuleKey, "InputKeyId", strInputKeyId ))
|
||||
if ( iotSuccess != m_ptrDiagData->getModProperty( stModuleKey, "InputKeyId", m_strInputKeyId ))
|
||||
{
|
||||
LOGERROR( "获取模块[%s]属性失败", m_stModKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
if ( iotSuccess != splitLongKeyIdTag( strInputKeyId, m_stPntInfo ))
|
||||
int nRet = m_ptrDiagData->getModProperty( stModuleKey, "IsOutputKeyId", m_strIsOutputKeyId );
|
||||
if ( nRet == iotSuccess && m_strIsOutputKeyId == "1" )
|
||||
{
|
||||
LOGERROR( "解析测点信息失败.KeyIdTag=[%s]", strInputKeyId.c_str());
|
||||
if ( iotSuccess != m_ptrDiagData->getValKeyByModOutput( stModuleKey, 2, m_stOutputKey2 ))
|
||||
{
|
||||
LOGERROR( "获取模块[%s]的输入输出参数失败", stModuleKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
}
|
||||
|
||||
if ( iotSuccess != splitLongKeyIdTag( m_strInputKeyId, m_stPntInfo ))
|
||||
{
|
||||
LOGERROR( "解析测点信息失败.KeyIdTag=[%s]", m_strInputKeyId.c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
@ -98,6 +109,7 @@ int CPntInput::init( const SFbdModKey &stModuleKey, const std::string & )
|
||||
int CPntInput::calculate()
|
||||
{
|
||||
SFbdNumericValue stOutput( 0, CN_FBD_STATUS_Invalid );
|
||||
SFbdStringValue stOutput2( m_strInputKeyId, CN_FBD_STATUS_Invalid );
|
||||
double dInValue = 0.0;
|
||||
int nInStatus = 0;
|
||||
|
||||
@ -107,9 +119,12 @@ int CPntInput::calculate()
|
||||
if ( m_ptrPointSub->isValidOfPntSta( m_nPntType, nInStatus ))
|
||||
{
|
||||
stOutput.m_nStatus = CN_FBD_STATUS_Valid;
|
||||
stOutput2.m_nStatus = CN_FBD_STATUS_Valid;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_strIsOutputKeyId == "1" )
|
||||
m_ptrDiagData->setStringValByKey( m_stOutputKey2, stOutput2 );
|
||||
return m_ptrDiagData->setNumericValByKey( m_stOutputKey, stOutput );
|
||||
}
|
||||
|
||||
|
||||
@ -45,6 +45,10 @@ private:
|
||||
SLongKeyIdTagInfo m_stPntInfo; //< 输入测点信息
|
||||
|
||||
SFbdValueKey m_stOutputKey; //< 输出key
|
||||
SFbdValueKey m_stOutputKey2; //< 第二个输出的key
|
||||
|
||||
std::string m_strInputKeyId; // 测点串
|
||||
std::string m_strIsOutputKeyId; // 是否输出测点串
|
||||
};
|
||||
|
||||
BOOST_DLL_ALIAS(
|
||||
|
||||
@ -33,6 +33,7 @@ CPntOutput::CPntOutput()
|
||||
m_nInValidPntStatus( 0 ),
|
||||
m_nSendIntervalMsec( 5000 ),
|
||||
m_lLastSendTimeMsec( 0L ),
|
||||
m_bEnableWhenStatusInvalid(false),
|
||||
m_ptrDiagData( nullptr )
|
||||
{
|
||||
}
|
||||
@ -55,6 +56,7 @@ int CPntOutput::init( const SFbdModKey &stModuleKey, const std::string &strExtra
|
||||
}
|
||||
|
||||
m_ptrDiagData = getFbdDiagDataApi();
|
||||
m_ptrOptCmdApi = getFbdDiagOptCmdApi();
|
||||
if ( m_ptrDiagData == nullptr )
|
||||
{
|
||||
LOGERROR( "获取Diagram数据接口单例失败" );
|
||||
@ -62,7 +64,8 @@ int CPntOutput::init( const SFbdModKey &stModuleKey, const std::string &strExtra
|
||||
}
|
||||
|
||||
//1.获取输入、输出参数
|
||||
if ( iotSuccess != m_ptrDiagData->getValKeyByModInput( stModuleKey, 1, m_stInKey1 ))
|
||||
if ( iotSuccess != m_ptrDiagData->getValKeyByModInput( stModuleKey, 1, m_stInKey1 ) ||
|
||||
iotSuccess != m_ptrDiagData->getValKeyByModInput( stModuleKey, 2, m_stInKeyEnable) )
|
||||
{
|
||||
LOGERROR( "获取模块[%s]的输入输出参数失败", stModuleKey.toString().c_str());
|
||||
return iotFailed;
|
||||
@ -71,7 +74,10 @@ int CPntOutput::init( const SFbdModKey &stModuleKey, const std::string &strExtra
|
||||
//< 获取参数
|
||||
{
|
||||
std::string strOutputKeyId;
|
||||
if ( iotSuccess != m_ptrDiagData->getModProperty( stModuleKey, "OutputKeyId", strOutputKeyId ))
|
||||
std::string strEnableWhenInvalid;
|
||||
|
||||
if ( iotSuccess != m_ptrDiagData->getModProperty( stModuleKey, "OutputKeyId", strOutputKeyId) ||
|
||||
iotSuccess != m_ptrDiagData->getModProperty(m_stModKey, "EnableWhenInvalid", strEnableWhenInvalid) )
|
||||
{
|
||||
LOGERROR( "获取模块[%s]属性失败", m_stModKey.toString().c_str());
|
||||
return iotFailed;
|
||||
@ -88,6 +94,16 @@ int CPntOutput::init( const SFbdModKey &stModuleKey, const std::string &strExtra
|
||||
LOGERROR( "解析模块[%s]关联的测点[%s]信息失败", stModuleKey.toString().c_str(), m_stPntInfo.strOriginalKey.c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_bEnableWhenStatusInvalid = boost::lexical_cast<int>(strEnableWhenInvalid) != 0;
|
||||
}
|
||||
catch ( const std::exception &e )
|
||||
{
|
||||
LOGERROR( "模块[%s]参数格式非法,Err:\n%s", m_stModKey.toString().c_str(), e.what());
|
||||
return iotFailed;
|
||||
}
|
||||
}
|
||||
|
||||
LOGINFO( "[%s]加载成功", m_stModKey.toString().c_str());
|
||||
@ -97,6 +113,21 @@ int CPntOutput::init( const SFbdModKey &stModuleKey, const std::string &strExtra
|
||||
|
||||
int CPntOutput::calculate()
|
||||
{
|
||||
SFbdNumericValue stInValEnable;
|
||||
if ( iotSuccess != m_ptrDiagData->getNumericValByKey( m_stInKeyEnable, stInValEnable ))
|
||||
{
|
||||
LOGERROR( "获取模块[%s]的输入 使能 的值失败", m_stModKey.toString().c_str());
|
||||
return iotFailed;
|
||||
}
|
||||
|
||||
//不使能直接返回,使能且需要判断状态是否有效时才进行状态的判断
|
||||
if ( 0 == static_cast<int>(stInValEnable.m_dValue) ||
|
||||
(!m_bEnableWhenStatusInvalid && !isValidOfStatus(stInValEnable.m_nStatus)))
|
||||
{
|
||||
return iotSuccess;//不使能,直接返回
|
||||
}
|
||||
|
||||
//使能,同时状态有效,则输出计算
|
||||
SFbdNumericValue stInput( 0, CN_FBD_STATUS_Invalid );
|
||||
|
||||
if ( iotSuccess != m_ptrDiagData->getNumericValByKey( m_stInKey1, stInput ))
|
||||
@ -106,6 +137,9 @@ int CPntOutput::calculate()
|
||||
m_stInKey1.toString().c_str());
|
||||
}
|
||||
|
||||
sendToDP( stInput );
|
||||
|
||||
/*
|
||||
//< 到定时周期,或者与上次值发生变化
|
||||
int64 lCurTime = iot_public::getMonotonicMsec();
|
||||
if ( lCurTime - m_lLastSendTimeMsec > m_nSendIntervalMsec || stInput != m_stLastValAndSta )
|
||||
@ -114,7 +148,7 @@ int CPntOutput::calculate()
|
||||
m_lLastSendTimeMsec = lCurTime;
|
||||
m_stLastValAndSta = stInput;
|
||||
}
|
||||
|
||||
*/
|
||||
return iotSuccess;
|
||||
}
|
||||
|
||||
@ -253,7 +287,7 @@ int CPntOutput::sendMsg( const std::string &strMsg )
|
||||
iot_idl::MT_OPT_SET_CAL_DATA_DOWN );
|
||||
objMsg.setPara1( m_nDomainIdOfPnt ); //TODO:需要填写吗?
|
||||
|
||||
if ( !m_objCommunicator.sendMsgToDomain( objMsg, m_nDomainIdOfPnt )) //< 发送到测点所在域
|
||||
if ( !m_ptrOptCmdApi->sendMsgToDomainByPublishCommunicator(objMsg, m_nDomainIdOfPnt )) //< 发送到测点所在域
|
||||
{
|
||||
LOGERROR( "模块[%s]发送消息到域[%d]-应用[%d]失败",
|
||||
m_stModKey.toString().c_str(), m_nDomainIdOfPnt, m_nAppIdOfPnt );
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "app_fbd/fbd_common/BaseModule.h"
|
||||
#include "app_fbd/fbd_common/FbdDiagDataApi.h"
|
||||
#include "app_fbd/fbd_common/FbdPointSubApi.h"
|
||||
#include "app_fbd/fbd_common/FbdDiagOptCmdApi.h"
|
||||
|
||||
namespace iot_app
|
||||
{
|
||||
@ -72,6 +73,7 @@ private:
|
||||
uint32 m_nInValidPntStatus; //< 测点无效状态位
|
||||
int m_nSendIntervalMsec; //< 数据断面发送间隔
|
||||
int64 m_lLastSendTimeMsec; //< 最后一次发送时间
|
||||
bool m_bEnableWhenStatusInvalid; //当使能值(输入参数2)的状态无效时,是否继续输出,0:不输出,1:输出
|
||||
|
||||
CFbdDiagDataApiPtr m_ptrDiagData; //< Diagram数据接口
|
||||
|
||||
@ -80,9 +82,10 @@ private:
|
||||
SLongKeyIdTagInfo m_stPntInfo; //< 输出测点信息
|
||||
|
||||
SFbdValueKey m_stInKey1; //< 输入参数1
|
||||
SFbdValueKey m_stInKeyEnable; //< 输入参数2,是否使能
|
||||
|
||||
SFbdNumericValue m_stLastValAndSta; //< 记录上一次的值
|
||||
iot_net::CMbCommunicator m_objCommunicator; //< 通信器
|
||||
CFbdDiagOptCmdApiPtr m_ptrOptCmdApi; //< opt服务接口
|
||||
};
|
||||
|
||||
BOOST_DLL_ALIAS(
|
||||
|
||||
@ -3,8 +3,18 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
//< 屏蔽xml_parser编译告警
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-copy"
|
||||
#endif
|
||||
|
||||
#include "boost/property_tree/xml_parser.hpp"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "boost/typeof/typeof.hpp"
|
||||
#include "boost/filesystem.hpp"
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include <QDateTime>
|
||||
#include <public/pub_sysinfo_api/SysInfoApi.h>
|
||||
#include "db_api_ex/CDbApi.h"
|
||||
#include "pub_widget/MessageBox.h"
|
||||
|
||||
QString getMethodStr(const QString& method){
|
||||
if(method == "smtp"){
|
||||
@ -33,15 +34,17 @@ QString getResult(int result){
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
CustomUiMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
setAutoLayout(true);
|
||||
|
||||
ui->setupUi(this);
|
||||
ui->tableWidget_pushHis->verticalHeader()->hide();
|
||||
refreshHis();
|
||||
|
||||
setWindowIcon( QIcon( ":push_debug.ico" ) );
|
||||
setWindowTitle( QObject::tr("推送服务调试") );
|
||||
setWindowTitle( QObject::tr("推送服务调试工具") );
|
||||
|
||||
connect(ui->pushButton_sendMail,&QPushButton::clicked,this,&MainWindow::sendMail_clicked);
|
||||
connect(ui->pushButton_bbiot_send,&QPushButton::clicked,this,&MainWindow::sendBbiot_clicked);
|
||||
@ -72,7 +75,7 @@ void MainWindow::sendMail_clicked()
|
||||
|| QString::number(ui->spinBox_port->value()) == ""
|
||||
)
|
||||
{
|
||||
QMessageBox::information(this,"提示","检查是否输入参数为空");
|
||||
N_MessageBox::information(this,"提示","检查是否输入参数为空");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -103,9 +106,9 @@ void MainWindow::sendMail_clicked()
|
||||
|
||||
|
||||
if(!m_objComm.sendMsgToDomain(msg)){
|
||||
QMessageBox::information(this,"提示","发送失败");
|
||||
N_MessageBox::information(this,"提示","发送失败");
|
||||
}else{
|
||||
QMessageBox::information(this,"提示","发送成功");
|
||||
N_MessageBox::information(this,"提示","发送成功");
|
||||
}
|
||||
|
||||
|
||||
@ -122,7 +125,7 @@ void MainWindow::sendBbiot_clicked()
|
||||
|| ui->lineEdit_bbiot_content->text() == ""
|
||||
)
|
||||
{
|
||||
QMessageBox::information(this,"提示","检查是否输入参数为空");
|
||||
N_MessageBox::information(this,"提示","检查是否输入参数为空");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -151,9 +154,9 @@ void MainWindow::sendBbiot_clicked()
|
||||
|
||||
|
||||
if(!m_objComm.sendMsgToDomain(msg)){
|
||||
QMessageBox::information(this,"提示","发送失败");
|
||||
N_MessageBox::information(this,"提示","发送失败");
|
||||
}else{
|
||||
QMessageBox::information(this,"提示","发送成功");
|
||||
N_MessageBox::information(this,"提示","发送成功");
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,7 +167,7 @@ void MainWindow::refreshHis()
|
||||
iot_dbms::CDbApi DbReadApi(DB_CONN_MODEL_READ);
|
||||
if(!DbReadApi.open())
|
||||
{
|
||||
QMessageBox::information(this,"提示","无法连接数据库");
|
||||
N_MessageBox::information(this,"提示","无法连接数据库");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -204,7 +207,7 @@ void MainWindow::refreshHis()
|
||||
|
||||
void MainWindow::emptyHis()
|
||||
{
|
||||
if ( QMessageBox::question(this,"提示","是否删除历史?") == QMessageBox::No)
|
||||
if ( N_MessageBox::question(this,"提示","是否删除历史?") != QMessageBox::Ok)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
@ -212,16 +215,16 @@ void MainWindow::emptyHis()
|
||||
iot_dbms::CDbApi DbReadApi(DB_CONN_MODEL_WRITE);
|
||||
if(!DbReadApi.open())
|
||||
{
|
||||
QMessageBox::information(this,"提示","无法连接数据库");
|
||||
N_MessageBox::information(this,"提示","无法连接数据库");
|
||||
return;
|
||||
}
|
||||
|
||||
if(DbReadApi.deleteRow("push_his"))
|
||||
{
|
||||
QMessageBox::information(this,"提示","删除成功");
|
||||
N_MessageBox::information(this,"提示","删除成功");
|
||||
ui->tableWidget_pushHis->setRowCount(0);
|
||||
}else{
|
||||
QMessageBox::information(this,"提示","删除失败");
|
||||
N_MessageBox::information(this,"提示","删除失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,12 +3,13 @@
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "net_msg_bus_api/CMbCommunicator.h"
|
||||
#include "pub_widget/CustomMainWindow.h"
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
class MainWindow : public CustomUiMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
@ -1,14 +1,48 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QApplication>
|
||||
#include "common/QtAppGlobalSet.h"
|
||||
#include "net_msg_bus_api/MsgBusApi.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
#include "pub_utility_api/FileStyle.h"
|
||||
#include "pub_widget/PubWidgetInit.h"
|
||||
|
||||
void loadStyle()
|
||||
{
|
||||
QString qss = QString();
|
||||
std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss","zh","light");
|
||||
|
||||
QFile qssfile1(QString::fromStdString(strFullPath));
|
||||
qssfile1.open(QFile::ReadOnly);
|
||||
if (qssfile1.isOpen())
|
||||
{
|
||||
qss += QLatin1String(qssfile1.readAll());
|
||||
qssfile1.close();
|
||||
}
|
||||
|
||||
strFullPath = iot_public::CFileStyle::getPathOfStyleFile("linkage_server_tool.qss","zh","light");
|
||||
QFile qssfile2(QString::fromStdString(strFullPath));
|
||||
qssfile2.open(QFile::ReadOnly);
|
||||
if (qssfile2.isOpen())
|
||||
{
|
||||
qss += QLatin1String(qssfile2.readAll());
|
||||
qssfile2.close();
|
||||
}
|
||||
|
||||
if (!qss.isEmpty())
|
||||
{
|
||||
qApp->setStyleSheet(qss);
|
||||
}
|
||||
|
||||
iot_public::installTranslator("zh");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
iot_common::doQtAppGlobalSet();
|
||||
|
||||
QApplication a(argc, argv);
|
||||
loadStyle();
|
||||
|
||||
iot_net::initMsgBus("push_debug","");
|
||||
int result;
|
||||
{
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
@ -32,7 +32,7 @@ HEADERS += \
|
||||
FORMS += \
|
||||
MainWindow.ui
|
||||
|
||||
LIBS += -lnet_msg_bus_api -lpub_sysinfo_api -lprotobuf -ldb_api_ex
|
||||
LIBS += -lnet_msg_bus_api -lpub_sysinfo_api -lprotobuf -ldb_api_ex -lpub_widget -lpub_utility_api
|
||||
|
||||
include($$PWD/../../idl_files/idl_files.pri)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user