#include "stdafx.h"
|
#include "Model.h"
|
#include "Log.h"
|
#include "Common.h"
|
#include "ToolUnits.h"
|
|
// ³£Á¿
|
|
|
CModel* g_pModel = NULL;
|
void CALLBACK ModerTimerProc(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
|
{
|
if (g_pModel != NULL) {
|
g_pModel->onTimer(nTimerid);
|
}
|
}
|
|
|
CModel::CModel()
|
{
|
m_pObservableEmitter = nullptr;
|
m_pObservable = nullptr;
|
m_nTimerID = 0;
|
}
|
|
|
CModel::~CModel()
|
{
|
for (auto item : m_mapPlc) {
|
delete item.second;
|
}
|
m_mapPlc.clear();
|
}
|
|
IObservable* CModel::getObservable()
|
{
|
return m_pObservable;
|
}
|
|
void CModel::setWorkDir(const char* pszWorkDir)
|
{
|
m_strWorkDir = pszWorkDir;
|
}
|
|
int CModel::init()
|
{
|
CString strIniFile;
|
CString strUnitId;
|
strIniFile.Format(_T("%s\\Configuration.ini"), (LPTSTR)(LPCTSTR)m_strWorkDir);
|
m_configuration.setFilepath((LPTSTR)(LPCTSTR)strIniFile);
|
m_configuration.getUnitId(strUnitId);
|
|
|
// Log
|
CString strLogDir;
|
strLogDir.Format(_T("%s\\BoounionPLCLog"), (LPTSTR)(LPCTSTR)m_strWorkDir);
|
::CreateDirectory(strLogDir, NULL);
|
CLog::GetLog()->SetOnLogCallback([&](int level, const char* pszMessage) -> void {
|
notifyTextAndInt(RX_CODE_LOG, pszMessage, level);
|
});
|
CLog::GetLog()->SetAutoAppendTimeString(TRUE);
|
CLog::GetLog()->SetOutputTarget(OT_FILE);
|
CLog::GetLog()->SetLogsDir(strLogDir);
|
CLog::GetLog()->SetEquipmentId((LPTSTR)(LPCTSTR)strUnitId);
|
LOGI("\r\n\r\n~~~ Prog Start! ~~~");
|
|
|
|
m_pObservable = RX_AllocaObservable([&](IObservableEmitter* e) -> void {
|
m_pObservableEmitter = e; // ±£´æ·¢ÉäÆ÷
|
});
|
|
|
m_nTimerID = (int)SetTimer(NULL, 1, 1000, (TIMERPROC)ModerTimerProc);
|
g_pModel = this;
|
|
|
// »ñÈ¡ËùÓÐPLCÐÅÏ¢
|
std::vector<PlcInfo> plcList;
|
m_configuration.getAllPLCInfo(plcList);
|
for (const auto& plc : plcList) {
|
addPlc(plc.strName, plc.strIp, plc.nPort);
|
}
|
|
return 0;
|
}
|
|
int CModel::term()
|
{
|
for (auto item : m_mapPlc) {
|
item.second->term();
|
}
|
CLog::GetLog()->SetOnLogCallback(nullptr);
|
return 0;
|
}
|
|
int CModel::notify(int code)
|
{
|
/* code */
|
if (m_pObservableEmitter != NULL) {
|
IAny* pAny = RX_AllocaAny();
|
if (pAny != NULL) {
|
pAny->addRef();
|
pAny->setCode(code);
|
m_pObservableEmitter->onNext(pAny);
|
pAny->release();
|
}
|
}
|
|
return 1;
|
}
|
|
int CModel::notifyPtr(int code, void* ptr/* = NULL*/)
|
{
|
/* code */
|
if (m_pObservableEmitter != NULL) {
|
IAny* pAny = RX_AllocaAny();
|
if (pAny != NULL) {
|
pAny->addRef();
|
pAny->setCode(code);
|
pAny->setPtrValue("ptr", ptr);
|
m_pObservableEmitter->onNext(pAny);
|
pAny->release();
|
}
|
}
|
|
return 1;
|
}
|
|
int CModel::notifyObj(int code, IRxObject* pObj)
|
{
|
/* code */
|
if (m_pObservableEmitter != NULL) {
|
IAny* pAny = RX_AllocaAny();
|
if (pAny != NULL) {
|
pAny->addRef();
|
pAny->setCode(code);
|
pAny->setObject("obj", pObj);
|
m_pObservableEmitter->onNext(pAny);
|
pAny->release();
|
}
|
}
|
|
return 1;
|
}
|
|
int CModel::notifyObjAndPtr(int code, IRxObject* pObj, void* ptr)
|
{
|
/* code */
|
if (m_pObservableEmitter != NULL) {
|
IAny* pAny = RX_AllocaAny();
|
if (pAny != NULL) {
|
pAny->addRef();
|
pAny->setCode(code);
|
pAny->setObject("obj", pObj);
|
pAny->setPtrValue("ptr", ptr);
|
m_pObservableEmitter->onNext(pAny);
|
pAny->release();
|
}
|
}
|
|
return 1;
|
}
|
|
int CModel::notifyInt(int code, int exCode)
|
{
|
if (m_pObservableEmitter != NULL) {
|
IAny* pAny = RX_AllocaAny();
|
if (pAny != NULL) {
|
pAny->addRef();
|
pAny->setCode(code);
|
pAny->setIntValue("exCode", exCode);
|
m_pObservableEmitter->onNext(pAny);
|
pAny->release();
|
}
|
}
|
|
return 0;
|
}
|
|
int CModel::notifyInt2(int code, int exCode, int exCode2)
|
{
|
if (m_pObservableEmitter != NULL) {
|
IAny* pAny = RX_AllocaAny();
|
if (pAny != NULL) {
|
pAny->addRef();
|
pAny->setCode(code);
|
pAny->setIntValue("exCode", exCode);
|
pAny->setIntValue("exCode2", exCode2);
|
m_pObservableEmitter->onNext(pAny);
|
pAny->release();
|
}
|
}
|
|
return 0;
|
}
|
|
int CModel::notifyDouble(int code, double dValue)
|
{
|
if (m_pObservableEmitter != NULL) {
|
IAny* pAny = RX_AllocaAny();
|
if (pAny != NULL) {
|
pAny->addRef();
|
pAny->setCode(code);
|
pAny->setDoubleValue("value", dValue);
|
m_pObservableEmitter->onNext(pAny);
|
pAny->release();
|
}
|
}
|
|
return 0;
|
}
|
|
int CModel::notifyObjAndInt(int code, IRxObject* pObj1, IRxObject* pObj2, int exCode)
|
{
|
if (m_pObservableEmitter != NULL) {
|
IAny* pAny = RX_AllocaAny();
|
if (pAny != NULL) {
|
pAny->addRef();
|
pAny->setCode(code);
|
if (pObj1 != nullptr) pAny->setObject("obj", pObj1);
|
if (pObj2 != nullptr) pAny->setObject("obj2", pObj2);
|
pAny->setIntValue("exCode", exCode);
|
m_pObservableEmitter->onNext(pAny);
|
pAny->release();
|
}
|
}
|
|
return 0;
|
}
|
|
int CModel::notifyText(int code, const char* pszText)
|
{
|
if (m_pObservableEmitter != NULL) {
|
IAny* pAny = RX_AllocaAny();
|
if (pAny != NULL) {
|
pAny->addRef();
|
pAny->setCode(code);
|
pAny->setStringValue("text", pszText);
|
m_pObservableEmitter->onNext(pAny);
|
pAny->release();
|
}
|
}
|
|
return 0;
|
}
|
|
int CModel::notifyTextAndInt(int code, const char* pszText, int exCode)
|
{
|
if (m_pObservableEmitter != NULL) {
|
IAny* pAny = RX_AllocaAny();
|
if (pAny != NULL) {
|
pAny->addRef();
|
pAny->setCode(code);
|
pAny->setStringValue("text", pszText);
|
pAny->setIntValue("exCode", exCode);
|
m_pObservableEmitter->onNext(pAny);
|
pAny->release();
|
}
|
}
|
|
return 0;
|
}
|
|
int CModel::notifyPtrAndInt(int code, void* ptr1, void* ptr2, int exCode)
|
{
|
if (m_pObservableEmitter != NULL) {
|
IAny* pAny = RX_AllocaAny();
|
if (pAny != NULL) {
|
pAny->addRef();
|
pAny->setCode(code);
|
pAny->setPtrValue("ptr", ptr1);
|
pAny->setPtrValue("ptr1", ptr1);
|
pAny->setPtrValue("ptr2", ptr2);
|
pAny->setIntValue("exCode", exCode);
|
m_pObservableEmitter->onNext(pAny);
|
pAny->release();
|
}
|
}
|
|
return 0;
|
}
|
|
int CModel::notifyMesMsg(int code, int stream, int function, const char* pszText)
|
{
|
if (m_pObservableEmitter != NULL) {
|
IAny* pAny = RX_AllocaAny();
|
if (pAny != NULL) {
|
pAny->addRef();
|
pAny->setCode(code);
|
pAny->setIntValue("stream", stream);
|
pAny->setIntValue("function", function);
|
pAny->setStringValue("text", pszText);
|
m_pObservableEmitter->onNext(pAny);
|
pAny->release();
|
}
|
}
|
|
return 0;
|
}
|
|
void CModel::onTimer(UINT nTimerid)
|
{
|
static int ii = 0;
|
ii++;
|
|
|
// ¼ì²âÊÇ·ñ¶Ï¿ª£¬ÖØÁ¬
|
if (ii % 5 == 0) {
|
for (auto item : m_mapPlc) {
|
if (!item.second->isConnected()) {
|
item.second->connect();
|
}
|
}
|
}
|
|
|
// ¶ÁÈ¡²úÄÜÐÅÏ¢
|
CPLC* pPlc = getCurrentPlc();
|
if (pPlc != nullptr) {
|
pPlc->readPLCDataRegularly();
|
}
|
}
|
|
std::map<std::string, CPLC*>& CModel::getPlcMap()
|
{
|
return m_mapPlc;
|
}
|
|
int CModel::addPlc(const char* pszName, const char* pszIp, const unsigned int port)
|
{
|
auto iter = m_mapPlc.find(pszName);
|
if (iter != m_mapPlc.end()) return -1;
|
CString strPlcDir;
|
strPlcDir.Format(_T("%s\\Plcs\\%s"), (LPTSTR)(LPCTSTR)m_strWorkDir, pszName);
|
CPLC* pPLC = new CPLC(pszName, pszIp, port);
|
pPLC->setWorkDir((LPTSTR)(LPCTSTR)strPlcDir);
|
PLCListener listener;
|
listener.onStateChanged = [&](void* pFrom, int state) -> void {
|
LOGD("PLC״̬¸Ä±ä£¬%d", state);
|
};
|
listener.onMonitorData = [&](void* pFrom, int id) -> void {
|
LOGD("PLConMonitorData£¬%d", id);
|
};
|
listener.onAlarm = [&](void* pFrom, CAlarm* pAlarm, int flag) -> void {
|
LOGE("onAlarm£¬%d %s", pAlarm->getId(), flag != 0 ? "ON" : "Off");
|
if (flag == 1) {
|
pAlarm->addRef();
|
notifyObjAndPtr(RX_CODE_ALARM_ON, pAlarm, pFrom);
|
pAlarm->release();
|
}
|
else {
|
pAlarm->addRef();
|
notifyObjAndPtr(RX_CODE_ALARM_OFF, pAlarm, pFrom);
|
pAlarm->release();
|
}
|
|
};
|
pPLC->setListener(listener);
|
pPLC->init();
|
m_mapPlc[pszName] = pPLC;
|
|
CString strDir;
|
strDir.Format(_T("%s\\PLCs\\%s"), (LPTSTR)(LPCTSTR)m_strWorkDir, (LPTSTR)(LPCTSTR)pszName);
|
CToolUnits::createDir(strDir);
|
m_configuration.addPLC(pszName, pszIp, port);
|
|
notifyPtr(RX_CODE_ADD_PLC, pPLC);
|
return 0;
|
}
|
|
int CModel::removePlc(const char* pszName)
|
{
|
auto iter = m_mapPlc.find(pszName);
|
if (iter == m_mapPlc.end()) return -1;
|
|
CString strDir;
|
strDir.Format(_T("%s\\PLCs\\%s"), (LPTSTR)(LPCTSTR)m_strWorkDir, (LPTSTR)(LPCTSTR)pszName);
|
CToolUnits::deleteDir(strDir);
|
m_configuration.removePLC(pszName);
|
|
notifyPtr(RX_CODE_REMOVE_PLC, iter->second);
|
delete iter->second;
|
m_mapPlc.erase(iter);
|
|
return 0;
|
}
|
|
void CModel::setCurrentPlc(CPLC* pPlc)
|
{
|
if (pPlc != nullptr) {
|
m_strCurrPlc = pPlc->getName();
|
} else {
|
m_strCurrPlc = "";
|
}
|
}
|
|
CPLC* CModel::getCurrentPlc()
|
{
|
auto item = m_mapPlc.find(m_strCurrPlc);
|
if (item != m_mapPlc.end()) {
|
return item->second;
|
}
|
|
return nullptr;
|
}
|