#include "stdafx.h"
|
#include "CBonder.h"
|
#include "Log.h"
|
#include "EQStateMonitor.h"
|
#include "CDataMonitor1.h"
|
#include "AlarmMonitor.h"
|
#include "LoadMonitor.h"
|
#include "ToolUnits.h"
|
#include "Model.h"
|
|
|
CBonder* g_pBonder = NULL;
|
void CALLBACK BonderTimerProc(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
|
{
|
if (g_pBonder != NULL) {
|
g_pBonder->onTimer(nTimerid);
|
}
|
}
|
|
UINT BoonderGetRecipeListThreadFunction(LPVOID lpParam)
|
{
|
DWORD_PTR* p = (DWORD_PTR*)lpParam;
|
CBonder* pBonder = (CBonder*)p[0];
|
BEQ::IEquipment* pEquipment = (BEQ::IEquipment*)p[1];
|
BEQ::IUnit* pUnit = (BEQ::IUnit*)p[2];
|
delete[] p;
|
return pBonder->GetRecipeListThreadFunction(pEquipment, pUnit);
|
}
|
|
CBonder::CBonder()
|
{
|
m_state = STATE_READY;
|
m_ullRunTime = 0;
|
m_ullStartTick = 0;
|
m_listener.onStateChanged = nullptr;
|
m_listener.onPlcStateChanged = nullptr;
|
m_listener.onRecvBroadcast = nullptr;
|
m_bAreYouThereRequest = TRUE;
|
m_strEquipmentModelType = "2860";
|
m_strSoftRev = "1.01";
|
m_pPlcData = nullptr;
|
m_pModel = nullptr;
|
m_bMute = false;
|
m_nVelocityRatio = 0;
|
m_dTactTime = 0.0;
|
m_nDayShiftCapacity = 0;
|
m_nNightShiftCapacity = 0;
|
InitializeCriticalSection(&m_criticalSection);
|
}
|
|
CBonder::~CBonder()
|
{
|
for (auto item : m_components) {
|
delete item;
|
}
|
m_components.clear();
|
clearRecipes();
|
|
DeleteCriticalSection(&m_criticalSection);
|
}
|
|
void CBonder::setWorkDir(const char* pszWorkDir)
|
{
|
m_strWorkDir = pszWorkDir;
|
}
|
|
void CBonder::setListener(BondListener& listener)
|
{
|
m_listener.onStateChanged = listener.onStateChanged;
|
m_listener.onPlcStateChanged = listener.onPlcStateChanged;
|
m_listener.onEfemStateChanged = listener.onEfemStateChanged;
|
m_listener.onRecvBroadcast = listener.onRecvBroadcast;
|
}
|
|
void CBonder::setModel(CModel* pModel)
|
{
|
m_pModel = pModel;
|
}
|
|
const std::vector<CComponent*>& CBonder::getComponents()
|
{
|
return m_components;
|
}
|
|
CPLC* CBonder::getPLC(const char* pszName)
|
{
|
return (CPLC*)GetComponent("PLC(1)");
|
}
|
|
int CBonder::save()
|
{
|
CFile file;
|
if (!file.Open(m_strFilepath.c_str(), CFile::modeCreate | CFile::modeWrite)) {
|
return -1;
|
}
|
|
CArchive ar(&file, CArchive::store);
|
Serialize(ar);
|
ar.Close();
|
file.Close();
|
|
return 0;
|
}
|
|
int CBonder::read(const char* pszFilepath)
|
{
|
CFile file;
|
m_strFilepath = pszFilepath;
|
if (!file.Open(pszFilepath, CFile::modeRead)) {
|
return -1;
|
}
|
|
CArchive ar(&file, CArchive::load);
|
Serialize(ar);
|
ar.Close();
|
file.Close();
|
|
return 0;
|
}
|
|
void CBonder::Serialize(CArchive& ar)
|
{
|
if (ar.IsStoring()) {
|
Lock();
|
Unlock();
|
}
|
else {
|
Lock();
|
|
Unlock();
|
}
|
|
for (auto item : m_components) {
|
item->Serialize(ar);
|
}
|
}
|
|
int CBonder::init()
|
{
|
// »úÆ÷״̬
|
CEQStateMonitor* pEQStateMonitor1 = new CEQStateMonitor();
|
pEQStateMonitor1->setName("»úÆ÷״̬");
|
pEQStateMonitor1->setDescription("»úÆ÷״̬");
|
pEQStateMonitor1->setIndex(0);
|
pEQStateMonitor1->setBeginAddr(4463 - 4400);
|
AddComponent(pEQStateMonitor1);
|
pEQStateMonitor1->init();
|
|
m_bMute = false;
|
|
// ³õʼ»¯¸÷ÖÖ×é¼þ
|
// ¶ÁPLC1ÅäÖÃ
|
// ¶ÁÈ¡»úÆ÷Ãû
|
CString strIniFile;
|
strIniFile.Format(_T("%s\\configuration.ini"), m_strWorkDir.c_str());
|
|
m_pPlcData = new char[1024];
|
char szIP[256];
|
unsigned int nPort;
|
BOOL bAutoSendData = FALSE;
|
GetPrivateProfileString("PLC1", "IP", _T(""), szIP, 256, strIniFile);
|
nPort = GetPrivateProfileInt("PLC1", "PORT", 8080, strIniFile);
|
bAutoSendData = GetPrivateProfileInt("Equipment", "AutoSendData", 0, strIniFile) != 0;
|
CPLC* pPlc = new CPLC("PLC1", szIP, nPort);
|
PLCListener listener;
|
listener.onStateChanged = [&](void* pFrom, int state) -> void {
|
if (m_listener.onPlcStateChanged != nullptr) {
|
m_listener.onPlcStateChanged(pFrom, state);
|
}
|
};
|
listener.onMonitorData = [&](void* pFrom, int id) -> void {
|
if (id == 1) {
|
for (auto c : m_components) {
|
c->onData(id, m_pPlcData, 200);
|
}
|
}
|
else if (id == 2) {
|
char szBuffer[24];
|
memset(szBuffer, 0, 24);
|
memcpy(szBuffer, &m_pPlcData[200+90*2], 20);
|
m_strCurRecipeName = szBuffer;
|
|
for (auto c : m_components) {
|
c->onData(id, &m_pPlcData[200], 200);
|
}
|
}
|
else if (id == 3) {
|
for (auto c : m_components) {
|
c->onData(id, &m_pPlcData[400], 184);
|
}
|
}
|
else if (id == MONITOR_ID_ALARM) {
|
for (auto c : m_components) {
|
c->onData(id, &m_pPlcData[600], 260);
|
}
|
}
|
};
|
pPlc->setListener(listener);
|
pPlc->addMonitor(1, 4400, 4499, MC::SOFT_COMPONENT::D, m_pPlcData);
|
pPlc->addMonitor(2, 4500, 4599, MC::SOFT_COMPONENT::D, &m_pPlcData[200]);
|
pPlc->addMonitor(3, 4700, 4791, MC::SOFT_COMPONENT::D, &m_pPlcData[400]);
|
pPlc->addMonitor(MONITOR_ID_ALARM, 10001, 10064, MC::SOFT_COMPONENT::M, &m_pPlcData[600]);
|
|
pPlc->setName("PLC(1)");
|
pPlc->setDescription("PLC");
|
pPlc->setIndex(0);
|
AddComponent(pPlc);
|
|
|
CDataMonitor1* pDataMonitor1 = new CDataMonitor1();
|
pDataMonitor1->setName("Êý¾Ý¼à¿Ø");
|
pDataMonitor1->setDescription("Õæ¿Õ¡¢Ñ¹Á¦ºÍζÈÊý¾Ý");
|
pDataMonitor1->setIndex(0);
|
pDataMonitor1->setResponseAddr(4425);
|
pDataMonitor1->enableAutoSendData(bAutoSendData);
|
AddComponent(pDataMonitor1);
|
pDataMonitor1->init();
|
|
|
CString strAlarmFile;
|
strAlarmFile.Format(_T("%s\\AlarmList.txt"), m_strWorkDir.c_str());
|
CAlarmMonitor* pAlarmMonitor1 = new CAlarmMonitor();
|
pAlarmMonitor1->setName("¾¯¸æÐÅÏ¢");
|
pAlarmMonitor1->setDescription("¾¯¸æÐÅÏ¢¼à¿Ø");
|
pAlarmMonitor1->setIndex(0);
|
pAlarmMonitor1->readAlarmListFromFile((LPTSTR)(LPCTSTR)strAlarmFile);
|
AddComponent(pAlarmMonitor1);
|
pAlarmMonitor1->init();
|
|
|
// LoadMonitor
|
CLoadMonitor* pLoadMonitor1 = new CLoadMonitor();
|
pLoadMonitor1->setName("ÉÏÏÂÁÏ");
|
pLoadMonitor1->setDescription("ÉÏÏÂÁÏÐÅºÅ¼à¿Ø");
|
pLoadMonitor1->setBeginAddr(4700);
|
pLoadMonitor1->setIndex(0);
|
AddComponent(pLoadMonitor1);
|
pLoadMonitor1->init();
|
|
|
// BEQÓëEFEMͨѶ
|
BEQ_CreateEquipment(m_pEquipment, m_strUnitId.c_str());
|
ASSERT(m_pEquipment != nullptr);
|
BEQ::EquipmentListener equListener;
|
equListener.onConnected = [&](void* pEquipment, const char* pszAddr, int port) -> void {
|
if (m_listener.onEfemStateChanged != nullptr) {
|
m_listener.onEfemStateChanged(this, pszAddr, port, 1);
|
}
|
LOGI("<Bonder>EFEMÁ¬½Ó½øÈë[%s:%d]", pszAddr, port);
|
};
|
equListener.onDisconnected = [&](void* pEquipment, const char* pszAddr, int port) -> void {
|
m_listener.onEfemStateChanged(this, pszAddr, port, 0);
|
LOGI("<Bonder>EFEMÁ¬½Ó¶Ï¿ª[%s:%d]", pszAddr, port);
|
};
|
equListener.onRunRecipe = [&](void* pEquipment, void* pUnit, int id) -> int {
|
return runRecipe((BEQ::IUnit*)pUnit, id);
|
};
|
equListener.onGetRecipeList = [&](void* pEquipment, void* pUnit) -> int {
|
getRecipeListInBlock((BEQ::IEquipment*)pEquipment, (BEQ::IUnit*)pUnit);
|
return 1;
|
};
|
equListener.onLoadReady = [&](void* pEquipment, void* pUnit, const char* pszMaterielId, const char* pszRecipeId) -> int {
|
return loadReady((BEQ::IUnit*)pUnit, pszMaterielId, pszRecipeId);
|
};
|
equListener.onLoadComplete = [&](void* pEquipment, void* pUnit, int layer) -> int {
|
return loadComplete((BEQ::IUnit*)pUnit, layer);
|
};
|
equListener.onUnloadComplete = [&](void* pEquipment, void* pUnit, int layer) -> int {
|
return unloadComplete((BEQ::IUnit*)pUnit, layer);
|
};
|
m_pEquipment->setEquipmentListener(equListener);
|
m_pEquipment->setVersion(m_strSoftRev.c_str());
|
m_pEquipment->addUnit(UNIT1, 5);
|
m_pEquipment->runOnServerMode(8192);
|
|
|
g_pBonder = this;
|
SetTimer(NULL, 1, 1000, (TIMERPROC)BonderTimerProc);
|
|
return 0;
|
}
|
|
int CBonder::term()
|
{
|
m_listener.onStateChanged = nullptr;
|
m_listener.onPlcStateChanged = nullptr;
|
m_listener.onRecvBroadcast = nullptr;
|
|
for (auto item : m_components) {
|
item->term();
|
}
|
|
if (m_pPlcData != nullptr) {
|
delete[] m_pPlcData;
|
m_pPlcData = nullptr;
|
}
|
|
return 0;
|
}
|
|
void CBonder::sendBroadcast(CComponent* pSender, CIntent* pIntent)
|
{
|
for (auto item : m_components) {
|
if (item != pSender) {
|
item->onRecvBroadcast(pSender, pIntent);
|
}
|
}
|
this->onRecvBroadcast(pSender, pIntent);
|
}
|
|
void CBonder::onRecvBroadcast(CComponent* pSender, CIntent* pIntent)
|
{
|
int code = pIntent->getCode();
|
if (m_listener.onRecvBroadcast != nullptr) {
|
m_listener.onRecvBroadcast(pSender, pIntent);
|
}
|
|
if (BC_CODE_RUN_RECIPE_RESULT == code) {
|
int errorCode = (int)(__int64)pIntent->getContext();
|
m_pEquipment->repLoadReadyComplete(errorCode);
|
}
|
}
|
|
void CBonder::setUnitId(const char* pszUnitId)
|
{
|
m_strUnitId = pszUnitId;
|
}
|
|
void CBonder::setEquipmentModelType(const char* pszModelType)
|
{
|
m_strEquipmentModelType = pszModelType;
|
}
|
|
void CBonder::setSoftRev(const char* pszSoftRev)
|
{
|
m_strSoftRev = pszSoftRev;
|
}
|
|
int CBonder::start()
|
{
|
Lock();
|
if (m_state == STATE_RUNNING) {
|
Unlock();
|
return -1;
|
}
|
|
if (m_state == STATE_ERROR) {
|
Unlock();
|
return -2;
|
}
|
|
LOGI("<Bonder>Start...");
|
m_state = STATE_RUNNING;
|
m_ullStartTick = GetTickCount64();
|
for (auto item : m_components) {
|
item->run();
|
}
|
Unlock();
|
|
if (m_listener.onStateChanged != nullptr) {
|
m_listener.onStateChanged(this, m_state);
|
}
|
|
|
return 0;
|
}
|
|
int CBonder::stop()
|
{
|
Lock();
|
if (m_state != STATE_RUNNING) {
|
Unlock();
|
return -1;
|
}
|
|
m_state = STATE_STOP;
|
m_ullRunTime += (GetTickCount64() - m_ullStartTick);
|
for (auto item : m_components) {
|
item->stop();
|
}
|
Unlock();
|
|
LOGI("<Bonder>Stop.");
|
if (m_listener.onStateChanged != nullptr) {
|
m_listener.onStateChanged(this, m_state);
|
}
|
|
|
return 0;
|
}
|
|
int CBonder::clearError()
|
{
|
Lock();
|
if (m_state != STATE_ERROR) {
|
Unlock();
|
return -1;
|
}
|
|
m_state = STATE_READY;
|
Unlock();
|
if (m_listener.onStateChanged != nullptr) {
|
m_listener.onStateChanged(this, m_state);
|
}
|
|
return 0;
|
}
|
|
BOOL CBonder::isRunning()
|
{
|
return m_state == STATE_RUNNING;
|
}
|
|
ULONGLONG CBonder::getRunTime()
|
{
|
if (m_state != STATE_RUNNING) {
|
return m_ullRunTime;
|
}
|
else {
|
return m_ullRunTime + (GetTickCount64() - m_ullStartTick);
|
}
|
}
|
|
void CBonder::onTimer(UINT nTimerid)
|
{
|
for (auto item : m_components) {
|
item->OnTimer(nTimerid);
|
}
|
|
|
// PLCÑÓʱÁ¬½Ó
|
static int nPlc = 0;
|
nPlc++;
|
if (nPlc == 3) {
|
CPLC* pPLC = (CPLC*)GetComponent("PLC(1)");
|
pPLC->init();
|
}
|
|
|
// ×Ô¶¯±£´æ
|
static int iii = 0;
|
iii++;
|
if (iii % 5 == 0) {
|
save();
|
}
|
|
// ÐèÒª¶¨Ê±¶ÁÈ¡µÄÊý¾Ý
|
readTaktTime();
|
|
|
|
|
|
// ²âÊÔ
|
BOOL bTest = FALSE;
|
if (bTest) {
|
static int xx = 0;
|
xx++;
|
memset(&m_pPlcData[600], 0, 260);
|
if (xx == 12) {
|
m_pPlcData[600] = 0x01;
|
for (auto c : m_components) {
|
c->onData(MONITOR_ID_ALARM, &m_pPlcData[600], 260);
|
}
|
}
|
else if (xx == 20) {
|
m_pPlcData[600] = 0x00;
|
for (auto c : m_components) {
|
c->onData(MONITOR_ID_ALARM, &m_pPlcData[600], 260);
|
}
|
}
|
}
|
}
|
|
void CBonder::AddComponent(CComponent* pComponent)
|
{
|
ASSERT(pComponent);
|
pComponent->setBonder(this);
|
m_components.push_back(pComponent);
|
}
|
|
CComponent* CBonder::GetComponent(const char* pszName)
|
{
|
for (auto c : m_components) {
|
if (c->getName().compare(pszName) == 0) {
|
return c;
|
}
|
}
|
|
return nullptr;
|
}
|
|
int CBonder::writeInt(int unitId, int addr, int value)
|
{
|
static CPLC* pPLC = nullptr;
|
if (pPLC == nullptr) {
|
pPLC = (CPLC*)GetComponent("PLC(1)");
|
}
|
ASSERT(pPLC);
|
pPLC->writeWord(MC::SOFT_COMPONENT::D, addr, value,
|
[&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
|
if (flag != 0) {
|
LOGE("<CBonder>writeInt³¬Ê±<unitId=%d,addr=%d,value=%d,flag=%d>", unitId, addr, value, flag);
|
}
|
});
|
|
return 0;
|
}
|
|
int CBonder::writeData(MC::SOFT_COMPONENT softComponent, unsigned int addr,
|
const char* pszData, unsigned int length, ONWRITE funOnWrite)
|
{
|
static CPLC* pPLC = nullptr;
|
if (pPLC == nullptr) {
|
pPLC = (CPLC*)GetComponent("PLC(1)");
|
}
|
ASSERT(pPLC);
|
return pPLC->writeData(softComponent, addr, pszData, length, funOnWrite);
|
}
|
|
int CBonder::readData(MC::SOFT_COMPONENT softComponent, unsigned int addr,
|
unsigned int readLen, ONREADDATA funOnRead)
|
{
|
static CPLC* pPLC = nullptr;
|
if (pPLC == nullptr) {
|
pPLC = (CPLC*)GetComponent("PLC(1)");
|
}
|
ASSERT(pPLC);
|
return pPLC->readData(softComponent, addr, readLen, funOnRead);
|
}
|
|
BOOL CBonder::readDataBlocking(HANDLE hEvent, MC::SOFT_COMPONENT softComponent, unsigned int addr,
|
unsigned int readLen, char* pszBuffer)
|
{
|
static CPLC* pPLC = nullptr;
|
if (pPLC == nullptr) {
|
pPLC = (CPLC*)GetComponent("PLC(1)");
|
}
|
ASSERT(pPLC);
|
|
BOOL bReadOk = FALSE;
|
BOOL bOutputLog = FALSE;
|
auto funOnReadData = [&](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
|
if (flag == 0) {
|
if (bOutputLog) {
|
CString s;
|
s.Format(_T("CBonder::readDataBlocking::funOnReadData %d ["), nDataSize);
|
for (unsigned int i = 0; i < nDataSize; i++) {
|
s.AppendFormat(" %x", (BYTE)pData[i]);
|
}
|
s.Append("]");
|
LOGI("<CBonder>Addr:%d, Received plc data.%s\n", addr, (LPTSTR)(LPCTSTR)s);
|
}
|
}
|
else {
|
LOGE("<CBonder>Addr:%d, PLCÅú¶ÁÈ¡Êý¾Ýλ³¬Ê±.flag=%d\n", addr, flag);
|
}
|
|
if (nDataSize == readLen && flag == 0) {
|
bReadOk = TRUE;
|
memcpy(pszBuffer, pData, readLen);
|
}
|
SetEvent(hEvent);
|
};
|
|
|
ResetEvent(hEvent);
|
pPLC->readData(softComponent, addr, readLen, funOnReadData);
|
WaitForSingleObject(hEvent, INFINITE);
|
|
return bReadOk;
|
}
|
|
BEQ::IEquipment* CBonder::getEquipment()
|
{
|
return m_pEquipment;
|
}
|
|
BEQ::IUnit* CBonder::getUnit(int index)
|
{
|
if (index == 0)
|
return m_pEquipment->getUnit(UNIT1);
|
|
return nullptr;
|
}
|
|
std::string& CBonder::getCurRecipeName()
|
{
|
return m_strCurRecipeName;
|
}
|
|
#define RECIPE_HEADER_SIZE 20 * 2
|
#define RECIPE_NAME_SIZE 10 * 2
|
#define RECIPE_SIZE 1140
|
int CBonder::getRecipeList()
|
{
|
CPLC* pPLC = (CPLC*)GetComponent("PLC(1)");
|
ASSERT(pPLC);
|
if (!pPLC->isConnected()) return -1;
|
clearRecipes();
|
|
HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
BOOL bOutputLog = TRUE;
|
BOOL bReadOk = FALSE;
|
char szBuffer[RECIPE_HEADER_SIZE];
|
char szRecipeName[RECIPE_NAME_SIZE + 4];
|
szRecipeName[RECIPE_NAME_SIZE] = '\0';
|
auto funOnReadData = [&](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
|
if (flag == 0) {
|
if (bOutputLog) {
|
CString s;
|
s.Format(_T("CPLC::monitorReadData::funOnReadData %d ["), nDataSize);
|
for (unsigned int i = 0; i < nDataSize; i++) {
|
s.AppendFormat(" %x", (BYTE)pData[i]);
|
}
|
s.Append("]");
|
TRACE("<CBonder>Addr:%d, Received plc data.%s\n", addr, (LPTSTR)(LPCTSTR)s);
|
}
|
}
|
else {
|
TRACE("<CBonder>Addr:%d, PLCÅú¶ÁÈ¡Êý¾Ýλ³¬Ê±.flag=%d\n", addr, flag);
|
}
|
|
if (nDataSize == RECIPE_HEADER_SIZE && flag == 0) {
|
bReadOk = TRUE;
|
memcpy(szBuffer, pData, RECIPE_HEADER_SIZE);
|
}
|
SetEvent(hEvent);
|
};
|
|
|
for (int i = 0; i < 100; i++) {
|
bReadOk = FALSE;
|
pPLC->readData(MC::SOFT_COMPONENT::ZR, 270000 + i*RECIPE_SIZE, RECIPE_HEADER_SIZE, funOnReadData);
|
WaitForSingleObject(hEvent, 3 * 1000);
|
ResetEvent(hEvent);
|
// ½âÊÍÊý¾ÝµÃµ½Åä·½
|
if (bReadOk) {
|
int id = (szBuffer[0] & 0xff) | (szBuffer[1] & 0xff) << 8
|
| (szBuffer[2] & 0xff) << 16 | (szBuffer[3] & 0xff) << 24;
|
int x = (szBuffer[28] & 0xff) | (szBuffer[29] & 0xff) << 8
|
| (szBuffer[30] & 0xff) << 16 | (szBuffer[31] & 0xff) << 24;
|
int y = (szBuffer[32] & 0xff) | (szBuffer[33] & 0xff) << 8
|
| (szBuffer[34] & 0xff) << 16 | (szBuffer[35] & 0xff) << 24;
|
int z = (szBuffer[36] & 0xff) | (szBuffer[37] & 0xff) << 8
|
| (szBuffer[38] & 0xff) << 16 | (szBuffer[39] & 0xff) << 24;
|
if (x > 0 && y > 0 && z > 0 && getRecipe(id) == nullptr) {
|
memcpy(szRecipeName, &szBuffer[4], RECIPE_NAME_SIZE);
|
Lock();
|
CRecipe* pRecipe = new CRecipe(id, szRecipeName);
|
m_recipes[id] = pRecipe;
|
Unlock();
|
}
|
// MYTRACE1("<Bonder>¶ÁÈ¡ %d,%s, xyz<%d,%d,%d>, OK\n", i, szRecipeName, x, y, z);
|
}
|
}
|
|
|
CloseHandle(hEvent);
|
return 0;
|
}
|
|
int CBonder::getRecipeListInBlock(BEQ::IEquipment* pEquipment, BEQ::IUnit* pUnit)
|
{
|
DWORD_PTR* p = new DWORD_PTR[3];
|
p[0] = (DWORD_PTR)this;
|
p[1] = (DWORD_PTR)pEquipment;
|
p[2] = (DWORD_PTR)pUnit;
|
CWinThread* pAcceptThread = AfxBeginThread(&BoonderGetRecipeListThreadFunction, (LPVOID)p,
|
THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
|
if (pAcceptThread) {
|
pAcceptThread->ResumeThread();
|
}
|
|
return 0;
|
}
|
|
UINT CBonder::GetRecipeListThreadFunction(BEQ::IEquipment* pEquipment, BEQ::IUnit* pUnit)
|
{
|
char szUnitName[256];
|
pUnit->getName(szUnitName, 256);
|
LOGI("<CBonder>ÕýÔÚ»ñÈ¡%sÅä·½", szUnitName);
|
getRecipeList();
|
LOGI("<CBonder>»ñÈ¡%sÅä·½Íê³É", szUnitName);
|
|
for (auto item : m_recipes) {
|
pUnit->addRecipe(item.first, item.second->getName().c_str(), false);
|
}
|
pEquipment->repRecipeListComplete();
|
|
return 0;
|
}
|
|
int CBonder::runRecipe(BEQ::IUnit* pUnit, int id)
|
{
|
char szUnitName[256];
|
pUnit->getName(szUnitName, 256);
|
LOGI("<CBonder>%sÕýÔÚÇл»Åä·½-%d", szUnitName, id);
|
|
CPLC* pPLC = (CPLC*)GetComponent("PLC(1)");
|
ASSERT(pPLC);
|
if (!pPLC->isConnected()) return -1;
|
|
|
// ÏÈдÊý¾Ýµ½plc
|
HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
BOOL bWrite = TRUE;
|
char szBuffer[8];
|
szBuffer[0] = (2 & 0xff);
|
szBuffer[1] = (2 & 0xff00) >> 8;
|
szBuffer[2] = 0;
|
szBuffer[3] = 0;
|
szBuffer[4] = (id & 0xff);
|
szBuffer[5] = (id & 0xff00) >> 8;
|
szBuffer[6] = (id & 0xff0000) >> 16;
|
szBuffer[7] = (id & 0xff000000) >> 24;
|
pPLC->writeData(MC::SOFT_COMPONENT::D, 4615, szBuffer, 8, [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
|
if (flag != 0) {
|
LOGE("<CBonder::runRecipe-%d>PLC1дÊý¾Ý³¬Ê±.flag=%d", flag, __LINE__);
|
bWrite = FALSE;
|
}
|
SetEvent(hEvent);
|
});
|
WaitForSingleObject(hEvent, INFINITE);
|
ResetEvent(hEvent);
|
if (!bWrite) {
|
CloseHandle(hEvent);
|
return -2;
|
}
|
|
|
// È»ºó´ÓPLC¶Á½á¹û
|
BOOL bOutputLog = FALSE;
|
BOOL bReadOk = FALSE;
|
Sleep(5000);
|
auto funOnReadData = [&](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
|
if (flag == 0) {
|
if (bOutputLog) {
|
CString s;
|
s.Format(_T("CPLC::runRecipe::funOnReadData %d ["), nDataSize);
|
for (unsigned int i = 0; i < nDataSize; i++) {
|
s.AppendFormat(" %x", (BYTE)pData[i]);
|
}
|
s.Append("]");
|
LOGI("<CBonder>Addr:%d, Received plc data.%s\n", addr, (LPTSTR)(LPCTSTR)s);
|
}
|
}
|
else {
|
LOGE("<CBonder::runRecipe>Addr:%d, PLCÅú¶ÁÈ¡Êý¾Ýλ³¬Ê±.flag=%d\n", addr, flag);
|
}
|
|
if (nDataSize == 2 && flag == 0) {
|
int value = (pData[0] & 0xff) | (pData[1] & 0xff) << 8;
|
bReadOk = (value == 2);
|
}
|
SetEvent(hEvent);
|
};
|
|
pPLC->readData(MC::SOFT_COMPONENT::D, 4630, 2, funOnReadData);
|
WaitForSingleObject(hEvent, INFINITE);
|
ResetEvent(hEvent);
|
|
|
// Çå¿Õ½á¹û
|
memset(szBuffer, 0, 8);
|
pPLC->writeData(MC::SOFT_COMPONENT::D, 4615, szBuffer, 8, [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
|
if (flag != 0) {
|
LOGE("<CBonder::runRecipe-%d>PLC1дÊý¾Ý³¬Ê±.flag=%d", flag, __LINE__);
|
bWrite = FALSE;
|
}
|
SetEvent(hEvent);
|
});
|
CloseHandle(hEvent);
|
|
|
if (bReadOk) {
|
LOGI("<CBonder>%sÇл»Åä·½-%dÍê³É", szUnitName, id);
|
return 0;
|
}
|
else {
|
LOGE("<CBonder>%sÇл»Åä·½-%dʧ°Ü", szUnitName, id);
|
return -3;
|
}
|
}
|
|
int CBonder::loadReady(BEQ::IUnit* pUnit, const char* pszMaterielId, const char* pszRecipeId)
|
{
|
char szUnitName[256];
|
pUnit->getName(szUnitName, 256);
|
LOGI("<CBonder>%sÉÏÁÏ×¼±¸¾ÍÐ÷£¬MaterielId:%s, RecipeId:%s", szUnitName, pszMaterielId, pszRecipeId);
|
|
CPLC* pPLC = (CPLC*)GetComponent("PLC(1)");
|
ASSERT(pPLC);
|
if (!pPLC->isConnected()) {
|
return -1;
|
}
|
|
|
// Èç¹ûÊǵ¥ÔªA»òµ¥ÔªB, дÎïÁÏIDºÍÅä·½IDµ½PLC
|
CLoadMonitor* pLoadMonitor = nullptr;
|
if (strcmp(szUnitName, UNIT1) == 0) {
|
|
pLoadMonitor = (CLoadMonitor*)GetComponent("ÉÏÏÂÁÏ");
|
return pLoadMonitor->loadReady(pszMaterielId, pszRecipeId);
|
}
|
|
|
return -2;
|
}
|
|
int CBonder::loadComplete(BEQ::IUnit* pUnit, int layer)
|
{
|
char szUnitName[256];
|
pUnit->getName(szUnitName, 256);
|
LOGI("<CBonder>%sÉÏÁÏÍê³É£¬layer:%d", szUnitName, layer);
|
|
CPLC* pPLC = (CPLC*)GetComponent("PLC(1)");
|
ASSERT(pPLC);
|
if (!pPLC->isConnected()) {
|
return -1;
|
}
|
if (layer <= 0 || layer > 1) {
|
return -2;
|
}
|
|
// дBITλµ½PLC£¬ÒÔ¸æËßËüÉÏÁÏÍê³É
|
// D¼Ä´æÆ÷ËÆºõ²»Äܰ´Î»Ð´£¬ÏȶÁ³öÔÙдÈë
|
BOOL bOutputLog = FALSE;
|
BOOL bReadOk = FALSE;
|
char szBuffer[32];
|
HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
auto funOnReadData = [&](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
|
if (flag == 0) {
|
if (bOutputLog) {
|
CString s;
|
s.Format(_T("CPLC::loadComplete::funOnReadData %d ["), nDataSize);
|
for (unsigned int i = 0; i < nDataSize; i++) {
|
s.AppendFormat(" %x", (BYTE)pData[i]);
|
}
|
s.Append("]");
|
TRACE("<CBonder>Addr:%d, Received plc data.%s\n", addr, (LPTSTR)(LPCTSTR)s);
|
}
|
}
|
else {
|
LOGE("<CBonder>Addr:%d, PLCÅú¶ÁÈ¡Êý¾Ýλ³¬Ê±.flag=%d\n", addr, flag);
|
}
|
|
if (nDataSize == 6 && flag == 0) {
|
bReadOk = TRUE;
|
memcpy(szBuffer, pData, 6);
|
}
|
SetEvent(hEvent);
|
};
|
pPLC->readData(MC::SOFT_COMPONENT::D, 4710, 6, funOnReadData);
|
WaitForSingleObject(hEvent, INFINITE);
|
ResetEvent(hEvent);
|
if (!bReadOk) {
|
CloseHandle(hEvent);
|
LOGE("<CBonder>%sÉÏÁÏÍê³É£¬¶Á±ê־λʧ°Ü¡£layer:%d", szUnitName, layer);
|
return -3;
|
}
|
|
// д
|
int index, nFlagAddr;
|
if (strcmp(szUnitName, UNIT1) == 0) {
|
index = 0;
|
nFlagAddr = 4710;
|
szBuffer[index * 2] |= 0x02;
|
}
|
|
|
BOOL bWriteOk = TRUE;
|
pPLC->writeData(MC::SOFT_COMPONENT::D, nFlagAddr, &szBuffer[index * 2], 2, [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
|
if (flag != 0) {
|
LOGE("<CBonder::loadReady-%d>PLC1дÊý¾Ý³¬Ê±.flag=%d", __LINE__, flag);
|
bWriteOk = FALSE;
|
}
|
SetEvent(hEvent);
|
});
|
WaitForSingleObject(hEvent, INFINITE);
|
ResetEvent(hEvent);
|
CloseHandle(hEvent);
|
|
if (bWriteOk) {
|
LOGI("<CBonder>%sÉÏÁÏÍê³É£¬ÒÑдÈëPLC", szUnitName);
|
return 0;
|
}
|
else {
|
LOGE("<CBonder>%sÉÏÁÏÍê³É, дPLCÎÞÏìÓ¦", szUnitName);
|
return -4;
|
}
|
}
|
|
int CBonder::unloadComplete(BEQ::IUnit* pUnit, int layer)
|
{
|
char szUnitName[256];
|
pUnit->getName(szUnitName, 256);
|
LOGI("<CBonder>%sÏÂÁÏÍê³É£¬layer:%d", szUnitName, layer);
|
|
CPLC* pPLC = (CPLC*)GetComponent("PLC(1)");
|
ASSERT(pPLC);
|
if (!pPLC->isConnected()) {
|
return -1;
|
}
|
if (layer <= 0 || layer > 4) {
|
return -2;
|
}
|
|
// дBITλµ½PLC£¬ÒÔ¸æËßËüÉÏÁÏÍê³É
|
// D¼Ä´æÆ÷ËÆºõ²»Äܰ´Î»Ð´£¬ÏȶÁ³öÔÙдÈë
|
BOOL bOutputLog = FALSE;
|
BOOL bReadOk = FALSE;
|
char szBuffer[32];
|
HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
auto funOnReadData = [&](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void {
|
if (flag == 0) {
|
if (bOutputLog) {
|
CString s;
|
s.Format(_T("CPLC::unloadComplete::funOnReadData %d ["), nDataSize);
|
for (unsigned int i = 0; i < nDataSize; i++) {
|
s.AppendFormat(" %x", (BYTE)pData[i]);
|
}
|
s.Append("]");
|
LOGD("<CBonder>Addr:%d, Received plc data.%s\n", addr, (LPTSTR)(LPCTSTR)s);
|
}
|
}
|
else {
|
LOGE("<CBonder>Addr:%d, PLCÅú¶ÁÈ¡Êý¾Ýλ³¬Ê±.flag=%d\n", addr, flag);
|
}
|
|
if (nDataSize == 6 && flag == 0) {
|
bReadOk = TRUE;
|
memcpy(szBuffer, pData, 6);
|
}
|
SetEvent(hEvent);
|
};
|
pPLC->readData(MC::SOFT_COMPONENT::D, 4710, 6, funOnReadData);
|
WaitForSingleObject(hEvent, INFINITE);
|
ResetEvent(hEvent);
|
|
if (!bReadOk) {
|
CloseHandle(hEvent);
|
LOGE("<CBonder>%sÏÂÁÏÍê³É£¬¶Á±ê־λʧ°Ü¡£layer:%d", szUnitName, layer);
|
return -3;
|
}
|
|
// д
|
int index, nFlagAddr;
|
if (strcmp(szUnitName, UNIT1) == 0) {
|
index = 0;
|
nFlagAddr = 4710;
|
szBuffer[index * 2 + 1] |= 0x02;
|
}
|
|
|
BOOL bWriteOk = TRUE;
|
pPLC->writeData(MC::SOFT_COMPONENT::D, nFlagAddr, &szBuffer[index * 2], 2, [&](IMcChannel* pChannel, int addr, DWORD value, int flag) -> void {
|
if (flag != 0) {
|
LOGE("<CBonder::unloadReady-%d>PLC1дÊý¾Ý³¬Ê±.flag=%d", __LINE__, flag);
|
bWriteOk = FALSE;
|
}
|
SetEvent(hEvent);
|
});
|
WaitForSingleObject(hEvent, INFINITE);
|
ResetEvent(hEvent);
|
CloseHandle(hEvent);
|
|
if (bWriteOk) {
|
LOGI("<CBonder>%sÏÂÁÏÍê³É£¬ÒÑдÈëPLC", szUnitName);
|
return 0;
|
}
|
else {
|
LOGE("<CBonder>%sÏÂÁÏÍê³É, дPLCÎÞÏìÓ¦", szUnitName);
|
return -4;
|
}
|
}
|
|
void CBonder::clearRecipes()
|
{
|
for (auto item : m_recipes) {
|
delete item.second;
|
}
|
m_recipes.clear();
|
}
|
|
CRecipe* CBonder::getRecipe(int id)
|
{
|
auto iter = m_recipes.find(id);
|
if (iter == m_recipes.end()) return nullptr;
|
|
return iter->second;
|
}
|
|
bool CBonder::isMute()
|
{
|
return m_bMute;
|
}
|
|
void CBonder::setMute(bool bMute)
|
{
|
m_bMute = bMute;
|
}
|
|
double CBonder::getTackTime()
|
{
|
return m_dTactTime;
|
}
|
|
#define ADDR_NIGHT_SHIFT_CAPACTITY 2027
|
void CBonder::readTaktTime()
|
{
|
CPLC* pPlc = getPLC("PLC(1)");
|
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) {
|
bool bMute = CToolUnits::toInt16(&pData[0]) != 0;
|
if (m_bMute != bMute) {
|
m_bMute = bMute;
|
m_pModel->notify(RX_CODE_BONDER_BEEP);
|
}
|
}
|
};
|
pPlc->readData(MC::M, 1003, 2, funOnReadData);
|
}
|
|
{
|
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;
|
m_pModel->notifyInt(RX_CODE_BONDER_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;
|
m_pModel->notifyDouble(RX_CODE_BONDER_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;
|
m_pModel->notifyInt(RX_CODE_BONDER_DAY_SHIFT_CAPACTITY, nDayShiftCapacity);
|
}
|
if (nNightShiftCapacity != m_nNightShiftCapacity) {
|
m_nNightShiftCapacity = nNightShiftCapacity;
|
m_pModel->notifyInt(RX_CODE_BONDER_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 bValue0 = CToolUnits::toInt16(&pData[(1103 - nStartAddress) * 2]) != 0; // Æô¶¯
|
bool bValue1 = CToolUnits::toInt16(&pData[(1100 - nStartAddress) * 2]) != 0; // ×Ô¶¯
|
bool bValue2 = CToolUnits::toInt16(&pData[(1104 - nStartAddress) * 2]) != 0; // ÔÝÍ£
|
bool bValue3 = CToolUnits::toInt16(&pData[(1100 - nStartAddress) * 2]) != 0; // ÊÖ¶¯
|
bool bValue4 = CToolUnits::toInt16(&pData[(1003 - nStartAddress) * 2]) != 0; // ¾²Òô
|
bool bValue5 = CToolUnits::toInt16(&pData[(1150 - nStartAddress) * 2]) != 0; // ¸´Î»
|
bool bValue6 = CToolUnits::toInt16(&pData[(1114 - nStartAddress) * 2]) != 0; // ֹͣ
|
|
bValue4 = pData[0] & 0x8;
|
bValue3 = pData[100*2/8] & 0x1;
|
if (m_bBlBtnsStates[0] != bValue0) {
|
m_bBlBtnsStates[0] = bValue0;
|
m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN0, bValue0);
|
}
|
|
if (m_bBlBtnsStates[1] != bValue1) {
|
m_bBlBtnsStates[1] = bValue1;
|
m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN1, bValue1);
|
}
|
|
if (m_bBlBtnsStates[2] != bValue2) {
|
m_bBlBtnsStates[2] = bValue2;
|
m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN2, bValue2);
|
}
|
|
if (m_bBlBtnsStates[3] != bValue3) {
|
m_bBlBtnsStates[3] = bValue3;
|
m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN3, bValue3);
|
}
|
|
if (m_bBlBtnsStates[4] != bValue4) {
|
m_bBlBtnsStates[4] = bValue4;
|
m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN4, bValue4);
|
}
|
|
if (m_bBlBtnsStates[5] != bValue5) {
|
m_bBlBtnsStates[5] = bValue5;
|
m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN5, bValue5);
|
}
|
|
if (m_bBlBtnsStates[6] != bValue6) {
|
m_bBlBtnsStates[6] = bValue6;
|
m_pModel->notifyInt(RX_CODE_BONDER_STATES_BTN6, bValue6);
|
}
|
}
|
};
|
pPlc->readData(MC::M, nStartAddress, nReadSize, funOnReadData);
|
}
|
}
|