#include "stdafx.h"
|
#include "Model.h"
|
#include "Log.h"
|
#include "Common.h"
|
#include "ToolUnits.h"
|
|
// ³£Á¿
|
#define ADDR_NIGHT_SHIFT_CAPACTITY 2027
|
|
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();
|
}
|
}
|
}
|
}
|
|
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;
|
CPLC* pPLC = new CPLC(pszName, pszIp, port);
|
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();
|
}
|
}
|
|
CPLC* CModel::getCurrentPlc()
|
{
|
auto item = m_mapPlc.find(m_strCurrPlc);
|
if (item != m_mapPlc.end()) {
|
return item->second;
|
}
|
|
return nullptr;
|
}
|
|
void CModel::readPLCDataRegularly()
|
{
|
CPLC* pPlc = getCurrentPlc();
|
if (pPlc == nullptr || !pPlc->isConnected()) return;
|
|
{
|
auto funOnReadData = [this](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
|
if (nDataSize == 2 && flag == 0) {
|
int nVelocityRatio = CToolUnits::toInt16(&pData[0]);
|
if (nVelocityRatio != m_nVelocityRatio) {
|
m_nVelocityRatio = nVelocityRatio;
|
notifyInt(RX_CODE_VELOCITY_RATIO, m_nVelocityRatio);
|
}
|
}
|
};
|
pPlc->readData(MC::D, 530, 2, funOnReadData);
|
}
|
|
{
|
auto funOnReadData = [this](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
|
if (nDataSize == 2 && flag == 0) {
|
double dTactTime = (double)CToolUnits::toInt16(&pData[0]);
|
if (dTactTime != m_dTactTime) {
|
m_dTactTime = dTactTime;
|
notifyDouble(RX_CODE_TACT_TIME, m_dTactTime);
|
}
|
}
|
};
|
pPlc->readData(MC::ZR, 1500, 2, funOnReadData);
|
}
|
|
{
|
auto funOnReadData = [this](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
|
if (nDataSize == (ADDR_NIGHT_SHIFT_CAPACTITY - 2012 + 1) * 2 && flag == 0) {
|
int nDayShiftCapacity = CToolUnits::toInt16(&pData[0]);
|
int nNightShiftCapacity = CToolUnits::toInt16(&pData[(ADDR_NIGHT_SHIFT_CAPACTITY - 2012) * 2]);
|
if (nDayShiftCapacity != m_nDayShiftCapacity) {
|
m_nDayShiftCapacity = nDayShiftCapacity;
|
notifyInt(RX_CODE_DAY_SHIFT_CAPACTITY, nDayShiftCapacity);
|
}
|
if (nNightShiftCapacity != m_nNightShiftCapacity) {
|
m_nNightShiftCapacity = nNightShiftCapacity;
|
notifyInt(RX_CODE_NIGHT_SHIFT_CAPACTITY, nNightShiftCapacity);
|
}
|
|
}
|
};
|
pPlc->readData(MC::ZR, 2012, (ADDR_NIGHT_SHIFT_CAPACTITY - 2012 + 1) * 2, funOnReadData);
|
}
|
|
{
|
int nStartAddress = 1000;
|
int nEndAddress = 1200;
|
int nReadSize = (nEndAddress - nStartAddress + 1) * 2;
|
auto funOnReadData = [this, nStartAddress, nReadSize](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
|
if (nDataSize == nReadSize && flag == 0) {
|
bool bRun = CToolUnits::toInt16(&pData[(1103 - nStartAddress) * 2]) != 0; // Æô¶¯
|
bool bAuto = CToolUnits::toInt16(&pData[(1100 - nStartAddress) * 2]) != 0; // ×Ô¶¯
|
bool bPuase = CToolUnits::toInt16(&pData[(1104 - nStartAddress) * 2]) != 0; // ÔÝÍ£
|
bool bManual = CToolUnits::toInt16(&pData[(1100 - nStartAddress) * 2]) != 0; // ÊÖ¶¯
|
bool bBeep = CToolUnits::toInt16(&pData[(1003 - nStartAddress) * 2]) != 0; // ¾²Òô
|
bool bResetting = CToolUnits::toInt16(&pData[(1150 - nStartAddress) * 2]) != 0; // ¸´Î»
|
bool bStop = CToolUnits::toInt16(&pData[(1114 - nStartAddress) * 2]) != 0; // ֹͣ
|
|
if (m_bBlBtnsStates[0] != bRun) {
|
m_bBlBtnsStates[0] = bRun;
|
notifyInt(RX_CODE_ACTIVATE, bRun);
|
}
|
|
if (m_bBlBtnsStates[1] != bAuto) {
|
m_bBlBtnsStates[1] = bAuto;
|
notifyInt(RX_CODE_AUTO, bAuto);
|
}
|
|
if (m_bBlBtnsStates[2] != bPuase) {
|
m_bBlBtnsStates[2] = bPuase;
|
notifyInt(RX_CODE_PUASE, bPuase);
|
}
|
|
if (m_bBlBtnsStates[3] != bManual) {
|
m_bBlBtnsStates[3] = bManual;
|
notifyInt(RX_CODE_MANUAL, bManual);
|
}
|
|
if (m_bBlBtnsStates[4] != bBeep) {
|
m_bBlBtnsStates[4] = bBeep;
|
notifyInt(RX_CODE_BEEP, bBeep);
|
}
|
|
if (m_bBlBtnsStates[5] != bResetting) {
|
m_bBlBtnsStates[5] = bResetting;
|
notifyInt(RX_CODE_RESETTING, bResetting);
|
}
|
|
if (m_bBlBtnsStates[6] != bStop) {
|
m_bBlBtnsStates[6] = bStop;
|
notifyInt(RX_CODE_STOP, bStop);
|
}
|
}
|
};
|
pPlc->readData(MC::M, nStartAddress, nReadSize, funOnReadData);
|
}
|
}
|