#include "stdafx.h" #include "CEquipment.h" #include "ToolUnits.h" #include #include "CArm.h" #include "CGlassPool.h" #include "Servo.h" #include "GlassJson.h" namespace SERVO { CEquipment::CEquipment() : m_nID(0), m_strName(""), m_strDescription(""), m_station(0, 255) { m_bEnable = TRUE; m_listener = { }; m_alive = { FALSE, 0, FALSE }; m_bCimState = FALSE; m_bUpstreamInline = FALSE; m_bDownstreamInline = FALSE; m_bLocalAlarm = FALSE; m_bAutoRecipeChange = FALSE; m_bVCREnable[0] = FALSE; memset(m_bLinkSignalToUpstream, 0, sizeof(m_bLinkSignalToUpstream)); memset(m_bLinkSignalToDownstream, 0, sizeof(m_bLinkSignalToDownstream)); m_pCclink = nullptr; m_nBaseAlarmId = 0; m_pArm = nullptr; m_blockReadBit = { 0 }; m_nTestFlag = 0; InitializeCriticalSection(&m_criticalSection); } CEquipment::~CEquipment() { for (int i = 0; i < SLOT_MAX; i++) { CContext* pContext = m_slot[i].getContext(); if (pContext != nullptr) { m_slot[i].setContext(nullptr); } } for (auto item : m_mapStep) { delete item.second; } m_mapStep.clear(); for (auto item : m_inputPins) { delete item; } m_inputPins.clear(); for (auto item : m_outputPins) { delete item; } m_outputPins.clear(); DeleteCriticalSection(&m_criticalSection); } void CEquipment::SetEnable(BOOL bEnable) { m_bEnable = bEnable; } BOOL CEquipment::IsEnabled() const { return m_bEnable; } void CEquipment::setListener(EquipmentListener listener) { m_listener = listener; } void CEquipment::setCcLink(CCCLinkIEControl* pCcLink) { m_pCclink = pCcLink; } void CEquipment::setArm(CEquipment* pEquipment) { ASSERT(pEquipment->isArm()); ASSERT(!this->isArm()); m_pArm = pEquipment; } CEquipment* CEquipment::getArm() { return m_pArm; } void CEquipment::setBaseAlarmId(int nBaseId) { m_nBaseAlarmId = nBaseId; } int CEquipment::getBaseAlarmId() { return m_nBaseAlarmId; } void CEquipment::getProperties(std::vector>& container) { container.clear(); // 示例:将一些属性添加到容器 container.push_back(std::make_pair("DeviceName", "ServoMotor")); container.push_back(std::make_pair("SerialNumber", "123456789")); container.push_back(std::make_pair("Version", "1.0")); } std::map& CEquipment::getSteps() { return m_mapStep; } CStep* CEquipment::getStep(unsigned int addr) { auto iter = m_mapStep.find(addr); if (iter == m_mapStep.end()) return nullptr; return iter->second; } CStep* CEquipment::getStepWithName(const char* pszName) { for (auto item : m_mapStep) { if (item.second->getName().compare(pszName) == 0) { return item.second; } } return nullptr; } int CEquipment::addStep(unsigned int addr, CStep* pStep) { auto iter = m_mapStep.find(addr); if (iter != m_mapStep.end()) return -1; pStep->setEquipment(this); pStep->setID(addr); pStep->setCcLink(m_pCclink); m_mapStep[addr] = pStep; return 0; } void CEquipment::setProcessState(int nSlotNo, PROCESS_STATE state) { if (nSlotNo <= 0 || nSlotNo > 8) return; const auto prevState = m_processState[nSlotNo - 1]; m_processState[nSlotNo - 1] = state; onProcessStateChanged(nSlotNo, prevState, m_processState[nSlotNo - 1]); if (m_listener.onProcessStateChanged != nullptr) { m_listener.onProcessStateChanged(this, nSlotNo, prevState, m_processState[nSlotNo - 1]); } } void CEquipment::init() { initPins(); initSteps(); initSlots(); for (auto item : m_mapStep) { item.second->init(); } } void CEquipment::term() { for (auto item : m_mapStep) { item.second->term(); } } void CEquipment::initSteps() { } void CEquipment::setID(int nID) { m_nID = nID; } int CEquipment::getID() { return m_nID; } void CEquipment::setName(const char* pszName) { m_strName = pszName; } std::string& CEquipment::getName() { return m_strName; } void CEquipment::setDescription(const char* pszDescription) { m_strDescription = pszDescription; } std::string& CEquipment::getDescription() { return m_strDescription; } void CEquipment::setCurrentRecipe(const std::string& recipe) { Lock(); m_currentRecipe = recipe; Unlock(); } std::string CEquipment::getCurrentRecipe() { Lock(); std::string out = m_currentRecipe; Unlock(); return out; } void CEquipment::setStation(int network, int station) { m_station.nNetNo = network; m_station.nStNo = station; } const StationIdentifier& CEquipment::getStation() { return m_station; } void CEquipment::getAttributeVector(CAttributeVector& attrubutes) { attrubutes.clear(); unsigned int weight = 0; attrubutes.addAttribute(new CAttribute("Network", std::to_string(m_station.nNetNo).c_str(), "", weight++)); attrubutes.addAttribute(new CAttribute("Station", std::to_string(m_station.nStNo).c_str(), "", weight++)); attrubutes.addAttribute(new CAttribute("ID", std::to_string(m_nID).c_str(), "", weight++)); attrubutes.addAttribute(new CAttribute("Name", m_strName.c_str(), "", weight++)); attrubutes.addAttribute(new CAttribute("Description", m_strDescription.c_str(), "", weight++)); attrubutes.addAttribute(new CAttribute("Alive", this->isAlive() ? _T("TRUE") : _T("FALSE"), "", weight++)); attrubutes.addAttribute(new CAttribute("CIM State", m_bCimState ? _T("ON") : _T("OFF"), "", weight++)); attrubutes.addAttribute(new CAttribute("Upstream", m_bUpstreamInline ? _T("Inline") : _T("Offline"), "", weight++)); attrubutes.addAttribute(new CAttribute("Downstream", m_bDownstreamInline ? _T("Inline") : _T("Offline"), "", weight++)); attrubutes.addAttribute(new CAttribute("Local Alarm", m_bLocalAlarm ? _T("TRUE") : _T("FALSE"), "", weight++)); attrubutes.addAttribute(new CAttribute("Auto Recipe Change", m_bAutoRecipeChange ? _T("TRUE") : _T("FALSE"), "", weight++)); char szTemp[256]; for (int i = 0; i < VCR_MAX; i++) { sprintf_s(szTemp, 256, "VCR-%d", i + 1); attrubutes.addAttribute(new CAttribute(szTemp, m_bVCREnable[i] ? _T("Enable") : _T("Disable"), "", weight++)); } for (auto item : m_inputPins) { attrubutes.addAttribute(new CAttribute(item->getName().c_str(), std::to_string((int)item->getType()).c_str(), "", weight++)); } for (auto item : m_outputPins) { attrubutes.addAttribute(new CAttribute(item->getName().c_str(), std::to_string((int)item->getType()).c_str(), "", weight++)); } for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; CGlass* pGlass = (CGlass*)m_slot[i].getContext(); CGlass* pBuddy = nullptr; if (pGlass == nullptr) { attrubutes.addAttribute(new CAttribute(m_slot[i].getName().c_str(), "", "", weight++)); } else { pBuddy = pGlass->getBuddy(); if (pBuddy == nullptr) { attrubutes.addAttribute(new CAttribute(m_slot[i].getName().c_str(), pGlass->getID().c_str(), "", weight++)); } else { attrubutes.addAttribute(new CAttribute(m_slot[i].getName().c_str(), (pGlass->getID() + " -> " + pBuddy->getID()).c_str(), "", weight++)); } } } } void CEquipment::setReadBitBlock(unsigned int start, unsigned int end) { m_blockReadBit.type = (unsigned int)DeviceType::B; m_blockReadBit.start = start; m_blockReadBit.end = end; m_blockReadBit.size = (m_blockReadBit.end - m_blockReadBit.start + 1) / 8; ASSERT(m_blockReadBit.size < BLOCK_BUFFER_MAX); } MemoryBlock& CEquipment::getReadBitBlock() { return m_blockReadBit; } void CEquipment::setWriteBitBlock(unsigned int start, unsigned int end) { m_blockWriteBit.type = (unsigned int)DeviceType::LB; m_blockWriteBit.start = start; m_blockWriteBit.end = end; m_blockWriteBit.size = (m_blockWriteBit.end - m_blockWriteBit.start + 1) / 8; } MemoryBlock& CEquipment::getWriteBitBlock() { return m_blockWriteBit; } void CEquipment::onTimer(UINT nTimerid) { // 每隔一秒,检查一下ALIVE状态 static int tick = 0; tick++; if (tick % (4 * 1) == 0) { m_alive.count++; if (m_alive.alive && m_alive.count > ALIVE_TIMEOUT) { m_alive.alive = FALSE; if (m_listener.onAlive != nullptr) { m_listener.onAlive(this, m_alive.alive); } } } } void CEquipment::serialize(CArchive& ar) { if (ar.IsStoring()) { Lock(); for (int i = 0; i < SLOT_MAX; i++) { m_slot[i].serialize(ar); CGlass* pGlass = (CGlass *)m_slot[i].getContext(); if (pGlass != nullptr) { const std::string pretty = GlassJson::ToPrettyString(*pGlass); CString strPretty = CString(pretty.c_str()); ar << strPretty; CGlass* pBuddy = pGlass->getBuddy(); if (pBuddy != nullptr) { const std::string prettyBuddy = GlassJson::ToPrettyString(*pBuddy); CString strPrettyBuddy = CString(prettyBuddy.c_str()); ar << strPrettyBuddy; } } } Unlock(); } else { for (int i = 0; i < SLOT_MAX; i++) { m_slot[i].serialize(ar); if (m_slot[i].getTempContext() != nullptr) { CString strPretty; std::string pretty; ar >> strPretty; pretty = (LPTSTR)(LPCTSTR)strPretty; if (!pretty.empty()) { CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass(); GlassJson::FromString(pretty, *pGlass); m_slot[i].setContext(pGlass); if (!pGlass->getBuddyId().empty()) { CGlass* pBuddy = theApp.m_model.m_glassPool.allocaGlass(); CString strPrettyBuddy; std::string prettyBuddy; ar >> strPrettyBuddy; prettyBuddy = (LPTSTR)(LPCTSTR)strPrettyBuddy; GlassJson::FromString(prettyBuddy, *pBuddy); pGlass->forceSetBuddy(pBuddy); } } } } // 梳理各玻璃之间的绑定关系 /* Lock(); for (int i = 0; i < SLOT_MAX; i++) { CGlass* pGlass = (CGlass*)m_slot[i].getContext(); if (pGlass != nullptr) { std::string& strBuddyId = pGlass->getBuddyId(); if (!strBuddyId.empty()) { for (int j = 0; j < SLOT_MAX; j++) { CGlass* pBudy = (CGlass*)m_slot[j].getContext(); if (pBudy != nullptr && strBuddyId.compare(pBudy->getID()) == 0) { pGlass->setBuddy(pBudy); TRACE("绑定关系: %s <- %s\n", pGlass->getID().c_str(), pBudy->getID().c_str()); } } } } } Unlock(); */ } } void CEquipment::onReceiveLBData(const char* pszData, size_t size) { /* TRACE("%s onReceiveLBData: %d bytes\n", m_strName.c_str(), size); for (unsigned int i = 0; i < size; i++) { if (pszData[i] != 0) TRACE("%d[%x]\n", i, pszData[i]); } */ // 连接信号解释和保存 BOOL bFlag; int index = 0; for (int i = 0; i < 8; i++) { m_bLinkSignalToUpstream[i][SIGNAL_UPSTREAM_INLINE] = isBitOn(pszData, size, index + 0); m_bLinkSignalToUpstream[i][SIGNAL_UPSTREAM_TROUBLE] = isBitOn(pszData, size, index + 1); m_bLinkSignalToUpstream[i][SIGNAL_INTERLOCK] = isBitOn(pszData, size, index + 2); m_bLinkSignalToUpstream[i][SIGNAL_SEND_ABLE] = isBitOn(pszData, size, index + 3); index += 0x40; if (m_bLinkSignalToUpstream[i][SIGNAL_SEND_ABLE]) { onSendAble(i+1); } } index += 0x40 * 2; for (int i = 0; i < 8; i++) { m_bLinkSignalToDownstream[i][SIGNAL_UPSTREAM_INLINE] = isBitOn(pszData, size, index + 0); m_bLinkSignalToDownstream[i][SIGNAL_UPSTREAM_TROUBLE] = isBitOn(pszData, size, index + 1); m_bLinkSignalToDownstream[i][SIGNAL_INTERLOCK] = isBitOn(pszData, size, index + 2); m_bLinkSignalToDownstream[i][SIGNAL_RECEIVE_ABLE] = isBitOn(pszData, size, index + 3); index += 0x40; if (m_bLinkSignalToDownstream[0][SIGNAL_RECEIVE_ABLE]) { onReceiveAble(i + 1); } } // 其它信号及响应 index = 0x540; // alive bFlag = isBitOn(pszData, size, index); if (!equalBool(m_alive.flag, bFlag)) { m_alive.flag = bFlag; m_alive.count = 0; // 状态 if (!m_alive.alive) { m_alive.alive = TRUE; if (m_listener.onAlive != nullptr) { m_listener.onAlive(this, m_alive.alive); } } } // CIM State bFlag = isBitOn(pszData, size, ++index); if (!equalBool(m_bCimState, bFlag)) { m_bCimState = bFlag; if (m_listener.onCimStateChanged != nullptr) { m_listener.onCimStateChanged(this, m_bCimState); } } // UpstreamInline bFlag = isBitOn(pszData, size, ++index); if (!equalBool(m_bUpstreamInline, bFlag)) { m_bUpstreamInline = bFlag; } // DownstreamInline bFlag = isBitOn(pszData, size, ++index); if (!equalBool(m_bDownstreamInline, bFlag)) { m_bDownstreamInline = bFlag; } // LocalAlarm bFlag = isBitOn(pszData, size, ++index); if (!equalBool(m_bLocalAlarm, bFlag)) { m_bLocalAlarm = bFlag; } // AutoRecipeChange bFlag = isBitOn(pszData, size, ++index); if (!equalBool(m_bAutoRecipeChange, bFlag)) { m_bAutoRecipeChange = bFlag; } // VCR Enable bFlag = isBitOn(pszData, size, ++index); if (!equalBool(m_bVCREnable[0], bFlag)) { m_bVCREnable[0] = bFlag; } // 以下根据信号做流程处理 for (int i = 0; i < 7; i++) { CHECK_READ_STEP_SIGNAL(STEP_ID_EQMODE_CHANGED + i, pszData, size); } // process data report CHECK_READ_STEP_SIGNAL(STEP_ID_PROCESS_DATA_REPORT, pszData, size); // FAC Data report // CHECK_READ_STEP_SIGNAL(STEP_ID_FAC_DATA_REPORT, pszData, size); { SERVO::CStep* pStep = getStep(STEP_ID_FAC_DATA_REPORT); if (pStep != nullptr) { ((CReadStep*)pStep)->onReadSignal(TRUE); } } // 配方改变 CHECK_READ_STEP_SIGNAL(STEP_ID_CURRENT_RECIPE_CHANGE_REPORT, pszData, size); // 主配方上报 CHECK_READ_STEP_SIGNAL(STEP_ID_MASTER_RECIPE_LIST_REPORT, pszData, size); // 配方参数 CHECK_WRITE_STEP_SIGNAL(STEP_ID_RECIPE_PARAMETER_CMD_REPLY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_RECIPE_PARAMETER_REPORT, pszData, size); // CIM Mode CHECK_WRITE_STEP_SIGNAL(STEP_ID_CIMMODE_CHANGED_CMD_REPLY, pszData, size); // CIM Message Set cmd reply CHECK_WRITE_STEP_SIGNAL(STEP_ID_CIM_MSG_SET_CMD_REPLY, pszData, size); // CIM Message Clear cmd reply CHECK_WRITE_STEP_SIGNAL(STEP_ID_CIM_MSG_CLEAR_CMD_REPLY, pszData, size); // Datetime set cmd reply CHECK_WRITE_STEP_SIGNAL(STEP_ID_DATETIME_SET_CMD_REPLY, pszData, size); // vcr enable cmd reply CHECK_WRITE_STEP_SIGNAL(STEP_ID_VCR_ENABLE_CMD_REPLY, pszData, size); // EQ mode change cmd reply CHECK_WRITE_STEP_SIGNAL(STEP_ID_EQMODE_CHANGE_CMD_REPLY, pszData, size); // EQ Master recipe request cmd reply CHECK_WRITE_STEP_SIGNAL(STEP_ID_MASTER_RECIPE_LIST_CMD_REPLY, pszData, size); // CIM Message Confirm CHECK_READ_STEP_SIGNAL(STEP_ID_CIM_MSG_CONFIRM_REPORT, pszData, size); // VCR1 Event report CHECK_READ_STEP_SIGNAL(STEP_ID_VCR1_EVENT_REPORT, pszData, size); // EQ Job Event CHECK_READ_STEP_SIGNAL(STEP_ID_RECIVE_JOB_UPS1, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_RECIVE_JOB_UPS2, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_RECIVE_JOB_UPS3, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_RECIVE_JOB_UPS4, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_SENT_OUT_JOB_DOWNS1, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_SENT_OUT_JOB_DOWNS2, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_SENT_OUT_JOB_DOWNS3, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_SENT_OUT_JOB_DOWNS4, pszData, size); // Store Job Report #1~15 CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT1, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT2, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT3, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT4, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT5, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT6, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT7, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT8, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT9, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT10, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT11, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT12, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT13, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT14, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_STORE_JOB_REPORT15, pszData, size); // Fetched Out Job Report #1~15 CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT1, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT2, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT3, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT4, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT5, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT6, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT7, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT8, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT9, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT10, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT11, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT12, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT13, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT14, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_FETCHED_OUT_JOB_REPORT15, pszData, size); // CEqCassetteTranserStateStep CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_EMPTY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_LOAD_READY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_LOADED, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_INUSE, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_UNLOAD_READY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT1_BLOCKED, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_EMPTY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_LOAD_READY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_LOADED, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_INUSE, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_UNLOAD_READY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT2_BLOCKED, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_EMPTY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_LOAD_READY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_LOADED, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_INUSE, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_UNLOAD_READY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT3_BLOCKED, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_EMPTY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_LOAD_READY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_LOADED, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_INUSE, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_UNLOAD_READY, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_PORT4_BLOCKED, pszData, size); // robot cmd reply CHECK_WRITE_STEP_SIGNAL(STEP_ID_ROBOT_CMD_REPLY, pszData, size); // Indexer Operation Mode Change CHECK_WRITE_STEP_SIGNAL(STEP_ID_IN_OP_CMD_REPLY, pszData, size); // Panel Data Report CHECK_READ_STEP_SIGNAL(STEP_ID_PANEL_DATA_REPORT, pszData, size); // Panel Data Request CHECK_WRITE_STEP_SIGNAL(STEP_ID_PANEL_DATA_REQUEST, pszData, size); // Job Data Request CHECK_READ_STEP_SIGNAL(STEP_ID_JOB_DATA_REQUEST, pszData, size); // job process start/end report CHECK_READ_STEP_SIGNAL(STEP_ID_JOB_PROCESS_START_REPORT, pszData, size); CHECK_READ_STEP_SIGNAL(STEP_ID_JOB_PROCESS_END_REPORT, pszData, size); CHECK_WRITE_STEP_SIGNAL(STEP_ID_PROT1_CASSETTE_CTR_CMD_REPLY, pszData, size); CHECK_WRITE_STEP_SIGNAL(STEP_ID_PROT2_CASSETTE_CTR_CMD_REPLY, pszData, size); CHECK_WRITE_STEP_SIGNAL(STEP_ID_PROT3_CASSETTE_CTR_CMD_REPLY, pszData, size); CHECK_WRITE_STEP_SIGNAL(STEP_ID_PROT4_CASSETTE_CTR_CMD_REPLY, pszData, size); } BOOL CEquipment::isBitOn(const char* pszData, size_t size, int index) { int byteIndex, bitIndex; byteIndex = (index) / 8; bitIndex = (index) % 8; return CToolUnits::getBit(pszData[byteIndex], bitIndex); } BOOL CEquipment::equalBool(BOOL b1, BOOL b2) { return (b1 && b2) || (!b1 && !b2); } BOOL CEquipment::isAlive() { return m_alive.alive; } BOOL CEquipment::isCimOn() { return m_bCimState; } BOOL CEquipment::isUpstreamInline() { return m_bUpstreamInline; } BOOL CEquipment::isDownstreamInline() { return m_bDownstreamInline; } BOOL CEquipment::isLocalAlarm() { return m_bLocalAlarm; } BOOL CEquipment::isAutoRecipeChange() { return m_bAutoRecipeChange; } BOOL CEquipment::isVCREnable(unsigned int index) { if (index >= VCR_MAX) return FALSE; return m_bVCREnable[index]; } BOOL CEquipment::isLinkSignalUpstreamOn(unsigned int path, unsigned int signal) { if (path >= PATH_MAX) return FALSE; if (signal >= SIGNAL_MAX) return FALSE; return m_bLinkSignalToUpstream[path][signal]; } BOOL CEquipment::isLinkSignalDownstreamOn(unsigned int path, unsigned int signal) { if (path >= PATH_MAX) return FALSE; if (signal >= SIGNAL_MAX) return FALSE; return m_bLinkSignalToDownstream[path][signal]; } void CEquipment::setLinkSignalUpstream(unsigned int path, unsigned int signal, BOOL bOn) { if (path >= PATH_MAX) return; if (signal >= SIGNAL_MAX) return; m_bLinkSignalToUpstream[path][signal] = bOn; } void CEquipment::setLinkSignalUpstreamBlock(unsigned int path, BOOL* pSignal) { if (path >= PATH_MAX) return; for (int i = 0; i < SIGNAL_MAX; i++) { m_bLinkSignalToUpstream[path][i] = pSignal[i]; } } void CEquipment::setLinkSignalDownstream(unsigned int path, unsigned int signal, BOOL bOn) { if (path >= PATH_MAX) return; if (signal >= SIGNAL_MAX) return; m_bLinkSignalToDownstream[path][signal] = bOn; } void CEquipment::setLinkSignalDownstreamBlock(unsigned int path, BOOL* pSignal) { if (path >= PATH_MAX) return; for (int i = 0; i < SIGNAL_MAX; i++) { m_bLinkSignalToDownstream[path][i] = pSignal[i]; } } int CEquipment::onStepEvent(CStep* pStep, int code) { if (code == STEP_EVENT_READDATA) { if (isAlarmStep(pStep)) { SERVO::CEqAlarmStep* pEqAlarmStep = (SERVO::CEqAlarmStep*)pStep; int state = pEqAlarmStep->getAlarmState(); ASSERT(state == 0 || state == 1); if (m_listener.onAlarm != nullptr) { m_listener.onAlarm(this, state, pEqAlarmStep->getAlarmId(), pEqAlarmStep->getUnitId(), pEqAlarmStep->getAlarmLevel()); } return 1; } else if (pStep->getName().compare(STEP_STATUS) == 0) { SERVO::CEqStatusStep* pEqStatusStep = (SERVO::CEqStatusStep*)pStep; if (m_listener.onEqStatusChanged != nullptr) { const unsigned int unitId = pEqStatusStep->getUnitId(); const int status = pEqStatusStep->getStatus(unitId); const int reason = pEqStatusStep->getReasonCode(unitId); m_listener.onEqStatusChanged(this, (int)unitId, status, reason); } return 1; } else if (isCimMessageConfirmStep(pStep)) { SERVO::CEqReadIntStep* pEqReadIntStep = (SERVO::CEqReadIntStep*)pStep; int value = pEqReadIntStep->getValue(); // 此处将value按高低位拆分为message id和panel no. // 可能还需要上报到cim short msgId, panelNo; msgId = (value & 0xffff0000 >> 16); panelNo = (value & 0xffff); LOGI("Cim Message Confirm(msgID = %d, panel no.=%d).", msgId, panelNo); } /* else if (isVcrEventStep(pStep)) { SERVO::CEqVcrEventStep* pEqVcrEventStep = (SERVO::CEqVcrEventStep*)pStep; CVcrEventReport* pVcrEventReport = pEqVcrEventStep->getVcrEventReport(); ASSERT(pVcrEventReport); if (m_listener.onVcrEventReport != nullptr) { m_listener.onVcrEventReport(this, pVcrEventReport); } // 0426, 先固定返回1(OK) pEqVcrEventStep->setReturnCode(1); return 1; } */ } return 0; } CPin* CEquipment::addPin(PinType type, char* pszName) { // 不允许名字添加重复的pin CPin* pPin = getPin(pszName); if (pPin != nullptr) return nullptr; // 添加到Pin列表,看是输入pin或输出pin if (type == PinType::INPUT) { pPin = new CPin(this, type, pszName); m_inputPins.push_back(pPin); return pPin; } else if (type == PinType::OUTPUT) { pPin = new CPin(this, type, pszName); m_outputPins.push_back(pPin); return pPin; } return nullptr; } CPin* CEquipment::getPin(char* pszName) { for (auto item : m_inputPins) { if (item->getName().compare(pszName) == 0) { return item; } } for (auto item : m_outputPins) { if (item->getName().compare(pszName) == 0) { return item; } } return nullptr; } std::vector& CEquipment::getInputPins() { return m_inputPins; } std::vector& CEquipment::getOutputPins() { return m_outputPins; } CRecipeList* CEquipment::getRecipeList(int unitNo) { return m_recipesManager.getRecipeList(unitNo); } bool CEquipment::saveRecipeList(int unitNo, std::string& strFilepath) { return m_recipesManager.saveRecipeList(unitNo, strFilepath); } bool CEquipment::readRecipeList(int unitNo, std::string& strFilepath) { return m_recipesManager.readRecipeList(unitNo, strFilepath); } int CEquipment::recvIntent(CPin* pPin, CIntent* pIntent) { ASSERT(pPin); CPin* pFromPin = pPin->getConnectedPin(); ASSERT(pFromPin); CEquipment* pFromEq = pFromPin->getEquipment(); ASSERT(pFromEq); LOGD("<%s-%s>收到来自<%s.%s>的Intent<%d,%s,0x%x>", this->getName().c_str(), pPin->getName().c_str(), pFromEq->getName().c_str(), pFromPin->getName().c_str(), pIntent->getCode(), pIntent->getMsg(), pIntent->getContext()); // 以下解释处理数据 int code = pIntent->getCode(); // 测试 if (code == FLOW_TEST) { AfxMessageBox(pIntent->getMsg()); } return 0; } int CEquipment::fetchedOutJob(int port, CJobDataB* pJobDataB) { if (m_pArm == nullptr) { return -1; } // 找到指定的glass id, Lock(); CGlass* pContext = nullptr; for (int i = 0; i < SLOT_MAX; i++) { CGlass* pGlass = (CGlass*)m_slot[i].getContext(); if (pGlass != nullptr && compareJobData(pJobDataB, pGlass->getJobDataS())) { pContext = pGlass; if (pGlass != nullptr) pGlass->addRef(); m_slot[i].setContext(nullptr); break; } } if (pContext == nullptr) { Unlock(); return -3; } ((CArm*)m_pArm)->tempStore(pContext); pContext->release(); Unlock(); if (m_processState[port] != PROCESS_STATE::Ready) { setProcessState(port, PROCESS_STATE::Ready); } if (m_listener.onDataChanged != nullptr) { m_listener.onDataChanged(this, EDCC_FETCHOUT_JOB); } return 0; } int CEquipment::storedJob(int port, CJobDataB* pJobDataB, short putSlot) { if (m_pArm == nullptr) { return -1; } CGlass* pGlass = nullptr; if (((CArm*)m_pArm)->tempFetchOut(pGlass) != 0) { return -2; } ASSERT(pGlass); Lock(); pGlass->addPath(m_nID, getSlotUnit(putSlot), putSlot); CGlass* pBuddy = pGlass->getBuddy(); if (pBuddy != nullptr) pBuddy->addPath(m_nID, getSlotUnit(putSlot), putSlot); m_slot[putSlot - 1].setContext(pGlass); pGlass->release(); // tempFetchOut需要调用一次release Unlock(); /* if (m_processState != PROCESS_STATE::Processing) { setProcessState(PROCESS_STATE::Processing); } */ if (m_listener.onDataChanged != nullptr) { m_listener.onDataChanged(this, EDCC_STORED_JOB); } return 0; } BOOL CEquipment::hasGlass() { for (int i = 0; i < SLOT_MAX; i++) { if (m_slot[i].isEnable() && !m_slot[i].isEmpty()) { return TRUE; } } return FALSE; } CGlass* CEquipment::getGlass(const char* pszGlassId) { for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; CGlass* pGlass = (CGlass*)m_slot[i].getContext(); if (pGlass == nullptr) continue; if (pGlass->getID().compare(pszGlassId) == 0) { return pGlass; } } return nullptr; } CGlass* CEquipment::getGlassFromSlot(int slotNo) { CSlot* pSlot = nullptr; for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; if (m_slot[i].getNo() != slotNo) continue; pSlot = &m_slot[i]; break; } if (pSlot != nullptr) { return (CGlass*)pSlot->getContext(); } return nullptr; } CGlass* CEquipment::getGlassWithCassette(int cassetteSequenceNo, int jobSequenceNo) { for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; CGlass* pGlass = (CGlass*)m_slot[i].getContext(); if (pGlass == nullptr) continue; CJobDataS* pJobDataS = pGlass->getJobDataS(); ASSERT(pJobDataS); if (pJobDataS->getCassetteSequenceNo() == cassetteSequenceNo && pJobDataS->getJobSequenceNo() == jobSequenceNo) { return pGlass; } } return nullptr; } int CEquipment::getAllGlass(std::vector& glasses) { Lock(); for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; CGlass* pGlass = (CGlass*)m_slot[i].getContext(); if (pGlass != nullptr) { pGlass->addRef(); glasses.push_back(pGlass); } } Unlock(); return (int)glasses.size(); } CJobDataS* CEquipment::getJobDataSWithCassette(int cassetteSequenceNo, int jobSequenceNo) { CSlot* pSlot = nullptr; for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; CGlass* pGlass = (CGlass*)m_slot[i].getContext(); if (pGlass == nullptr) continue; CJobDataS* pJobDataS = pGlass->getJobDataS(); ASSERT(pJobDataS); if (pJobDataS->getCassetteSequenceNo() == cassetteSequenceNo && pJobDataS->getJobSequenceNo() == jobSequenceNo) { return pJobDataS; } } return nullptr; } bool CEquipment::isAlarmStep(SERVO::CStep* pStep) { return CToolUnits::startsWith(pStep->getName(), STEP_ALARM_START); } bool CEquipment::isPortTypeStep(SERVO::CStep* pStep) { std::regex pattern("^EQPort\\d+Type$"); return std::regex_match(pStep->getName(), pattern); } bool CEquipment::isPortModeStep(SERVO::CStep* pStep) { std::regex pattern("^EQPort\\d+Mode$"); return std::regex_match(pStep->getName(), pattern); } bool CEquipment::isPortCassetteTypeStep(SERVO::CStep* pStep) { std::regex pattern("^EQPort\\d+CassetteType$"); return std::regex_match(pStep->getName(), pattern); } bool CEquipment::isPortTransferModeStep(SERVO::CStep* pStep) { std::regex pattern("^EQPort\\d+TransferMode$"); return std::regex_match(pStep->getName(), pattern); } bool CEquipment::isPortEnableStep(SERVO::CStep* pStep) { std::regex pattern("^EQPort\\d+Enable$"); return std::regex_match(pStep->getName(), pattern); } bool CEquipment::isPortTypeAutoChangeEnableStep(SERVO::CStep* pStep) { std::regex pattern("^EQPort\\d+CassetteType$"); return std::regex_match(pStep->getName(), pattern); } bool CEquipment::isCassetteTransferStateStep(SERVO::CStep* pStep) { std::regex pattern("^EQPort\\d+Cassette.*"); return std::regex_match(pStep->getName(), pattern); } bool CEquipment::isCimMessageConfirmStep(SERVO::CStep* pStep) { return pStep->getName().compare(STEP_EQ_CIM_MESSAGE_CONFIRM) == 0; } bool CEquipment::isVcrEventStep(SERVO::CStep* pStep) { return pStep->getName().compare(STEP_EQ_VCR1_EVENT_REPORT) == 0; } int CEquipment::setEqMode(short mode) { SERVO::CEqModeChangeStep* pStep = (SERVO::CEqModeChangeStep*)getStepWithName(STEP_EQ_MODE_CHANGE); if (pStep == nullptr) { return -1; } return pStep->setEqMode(mode); } int CEquipment::setCimMode(BOOL bOn) { SERVO::CEqCimModeChangeStep* pStep = (SERVO::CEqCimModeChangeStep*)getStepWithName(STEP_CIM_MODE_CHANGE); if (pStep == nullptr) { return -1; } if (bOn) return pStep->cimOn(); else return pStep->cimOff(); } int CEquipment::setCimMessage(const char* pszMessage, short id, short nTouchPanelNo) { SERVO::CEqCimMessageCmdStep* pStep = (SERVO::CEqCimMessageCmdStep*)getStepWithName(STEP_CIM_MESSAGE_CMD); if (pStep == nullptr) { return -1; } return pStep->setCimMessage(pszMessage, id, nTouchPanelNo); } int CEquipment::clearCimMessage(short id, short nTouchPanelNo) { SERVO::CEqCimMessageClearStep* pStep = (SERVO::CEqCimMessageClearStep*)getStepWithName(STEP_CIM_MESSAGE_CLEAR); if (pStep == nullptr) { return -1; } return pStep->clearCimMessage(id, nTouchPanelNo); } int CEquipment::setDateTime(short year, short month, short day, short hour, short minute, short second) { SERVO::CEqDateTimeSetCmdStep* pStep = (SERVO::CEqDateTimeSetCmdStep*)getStepWithName(STEP_DATETIME_SET_CMD); if (pStep == nullptr) { return -1; } return pStep->setDateTime(year, month, day, hour, minute, second); } int CEquipment::setDispatchingMode(DISPATCHING_MODE mode, ONWRITED onWritedBlock/* = nullptr*/) { SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getStepWithName(STEP_EQ_DISPATCHINT_MODE_CHANGE); if (pStep == nullptr) { return -1; } LOGI("准备设置DispatchingMode<%d>", m_strName.c_str(), (int)mode); if (onWritedBlock != nullptr) { pStep->writeShort((short)mode, onWritedBlock); } else { pStep->writeShort((short)mode, [&, mode](int code) -> int { if (code == WOK) { LOGI("设置DispatchingMode成功.", m_strName.c_str()); } else { LOGE("设置DispatchingMode失败,code:%d", m_strName.c_str(), code); } return 0; }); } return 0; } int CEquipment::indexerOperationModeChange(IDNEXER_OPERATION_MODE mode, ONWRITEDRET onWritedRetBlock) { SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getStepWithName(STEP_EQ_IN_OP_MODE_CHANGE); if (pStep == nullptr) { return -1; } unsigned short operationMode = (unsigned short)((unsigned short)mode + getIndexerOperationModeBaseValue()); LOGI("准备设置indexerOperationMode<%d>", m_strName.c_str(), (int)mode); pStep->writeShort(operationMode, [&, pStep, mode, onWritedRetBlock](int code) -> int { int retCode = 0; if (code == WOK) { LOGI("设置indexerOperationMode成功.", m_strName.c_str()); const char* pszRetData = nullptr; pStep->getReturnData(pszRetData); ASSERT(pszRetData); retCode = (unsigned int)CToolUnits::toInt16(pszRetData); LOGI("返回值: %d", m_strName.c_str(), retCode); } else { LOGE("设置indexerOperationMode失败,code:%d", m_strName.c_str(), code); } if (onWritedRetBlock != nullptr) { onWritedRetBlock(code, retCode); } return 0; }); return 0; } int CEquipment::masterRecipeListRequest(short unitNo, ONSYNCINGSTATECHANGED block) { SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getStepWithName(STEP_EQ_MASTER_RECIPE_LIST_REQ); if (pStep == nullptr) { return -1; } LOGI("正在请求单元<%d>主配方列表", m_strName.c_str(), unitNo); m_recipesManager.setOnSyncingStateChanged(block); if (m_recipesManager.syncing() != 0) { return -2; } pStep->writeShort(unitNo, [&, unitNo](int code) -> int { if (code == WOK) { LOGI("请求单元<%d>主配方列表成功,正在等待数据.", m_strName.c_str(), unitNo); } else { m_recipesManager.syncFailed(); LOGE("请求单元<%d>主配方列表失败,code:%d", m_strName.c_str(), unitNo, code); } return 0; }); return 0; } int CEquipment::recipeParameterRequest(short masterRecipeId, short localRecipeId, short unitNo, ONSYNCINGSTATECHANGED block) { LOGI("正在请求单元<%d>主配参数列表", m_strName.c_str(), unitNo); m_recipesManager.setOnSyncingStateChanged(block); if (m_recipesManager.syncing() != 0) { return -2; } SERVO::CEqWriteStep* pStep = (SERVO::CEqWriteStep*)getStepWithName(STEP_EQ_RECIPE_PARAMETER_REQ); if (pStep == nullptr) { return -1; } char szBuffer[14 * 2] = {0}; int index = 0; memcpy(&szBuffer[index], &masterRecipeId, sizeof(short)); index += sizeof(short); memcpy(&szBuffer[index], &localRecipeId, sizeof(short)); index += sizeof(short); memcpy(&szBuffer[index], &unitNo, sizeof(short)); pStep->writeDataEx(szBuffer, 14 * 2, [&, unitNo](int code) -> int { if (code == WOK) { LOGI("请求单元<%d>主配方参数列表成功,正在等待数据.", m_strName.c_str(), unitNo); } else { m_recipesManager.syncFailed(); LOGE("请求单元<%d>主配方参数列表失败,code:%d", m_strName.c_str(), unitNo, code); } return 0; }); return 0; } CSlot* CEquipment::getAvailableSlot() { for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; if (m_slot[i].isLock()) continue; if (!m_slot[i].isEmpty()) continue; return &m_slot[i]; } return nullptr; } CSlot* CEquipment::getAvailableSlotForGlass(MaterialsType type) { for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; if (m_slot[i].isLock()) continue; if (!m_slot[i].isEmpty()) continue; int lsPath = m_slot[i].getLinkSignalPath(); if (!m_bLinkSignalToDownstream[lsPath][SIGNAL_UPSTREAM_INLINE] || m_bLinkSignalToDownstream[lsPath][SIGNAL_UPSTREAM_TROUBLE] || !m_bLinkSignalToDownstream[lsPath][SIGNAL_INTERLOCK] || !m_bLinkSignalToDownstream[lsPath][SIGNAL_RECEIVE_ABLE]) continue; MaterialsType slotType = m_slot[i].getType(); if (type == MaterialsType::G1 && slotType == MaterialsType::G2) continue; if (type == MaterialsType::G2 && slotType == MaterialsType::G1) continue; return &m_slot[i]; } return nullptr; } CSlot* CEquipment::getAvailableSlotForGlassExcludeSignal(MaterialsType type) { for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; if (m_slot[i].isLock()) continue; if (!m_slot[i].isEmpty()) continue; MaterialsType slotType = m_slot[i].getType(); if (type == MaterialsType::G1 && slotType == MaterialsType::G2) continue; if (type == MaterialsType::G2 && slotType == MaterialsType::G1) continue; return &m_slot[i]; } return nullptr; } CSlot* CEquipment::getAvailableSlotForGlass2(MaterialsType type, const std::vector& candidates) { for (auto item : candidates) { for (int i = 0; i < SLOT_MAX; i++) { if (item == i + 1) { if (!m_slot[i].isEnable()) continue; if (m_slot[i].isLock()) continue; if (!m_slot[i].isEmpty()) continue; int lsPath = m_slot[i].getLinkSignalPath(); if (!m_bLinkSignalToDownstream[lsPath][SIGNAL_UPSTREAM_INLINE] || m_bLinkSignalToDownstream[lsPath][SIGNAL_UPSTREAM_TROUBLE] || !m_bLinkSignalToDownstream[lsPath][SIGNAL_INTERLOCK] || !m_bLinkSignalToDownstream[lsPath][SIGNAL_RECEIVE_ABLE]) continue; MaterialsType slotType = m_slot[i].getType(); if (type == MaterialsType::G1 && slotType == MaterialsType::G2) continue; if (type == MaterialsType::G2 && slotType == MaterialsType::G1) continue; return &m_slot[i]; } } } return nullptr; } CSlot* CEquipment::isSlotAvailable(unsigned int slot) { if (slot >= 8) return nullptr; if (!m_slot[slot].isEnable()) return nullptr; if (m_slot[slot].isLock()) return nullptr; if (!m_slot[slot].isEmpty()) return nullptr; int lsPath = m_slot[slot].getLinkSignalPath(); if (!m_bLinkSignalToDownstream[lsPath][SIGNAL_UPSTREAM_INLINE] || m_bLinkSignalToDownstream[lsPath][SIGNAL_UPSTREAM_TROUBLE] || !m_bLinkSignalToDownstream[lsPath][SIGNAL_INTERLOCK] || !m_bLinkSignalToDownstream[lsPath][SIGNAL_RECEIVE_ABLE]) return nullptr; return &m_slot[slot]; } CSlot* CEquipment::getNonEmptySlot(MaterialsType putSlotType) { for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; if (m_slot[i].isLock()) continue; CGlass* pGlass = (CGlass*)m_slot[i].getContext(); if (pGlass == nullptr) continue; MaterialsType glassType = pGlass->getType(); if (glassType == MaterialsType::G1 && putSlotType == MaterialsType::G2) continue; if (glassType == MaterialsType::G2 && putSlotType == MaterialsType::G1) continue; return &m_slot[i]; } return nullptr; } CSlot* CEquipment::getProcessedSlot(MaterialsType putSlotType, BOOL bJobMode/* = FALSE*/) { for (int i = 0; i < SLOT_MAX; i++) { if (m_nTestFlag == 1) LOGD("getProcessedSlot 001"); if (!m_slot[i].isEnable()) continue; if (m_nTestFlag == 1) LOGD("getProcessedSlot 002"); if (m_slot[i].isLock()) continue; if (m_nTestFlag == 1) LOGD("getProcessedSlot 003"); CGlass* pGlass = (CGlass*)m_slot[i].getContext(); if (!isSlotProcessed(i)) continue; if (m_nTestFlag == 1) LOGD("getProcessedSlot 004"); if (pGlass == nullptr) continue; if (m_nTestFlag == 1) LOGD("getProcessedSlot 005"); if (!pGlass->isScheduledForProcessing()) continue; if (m_nTestFlag == 1) LOGD("getProcessedSlot 006"); if (bJobMode && pGlass->getProcessJob() == nullptr) continue; if (m_nTestFlag == 1) LOGD("getProcessedSlot 007"); if(pGlass->getInspResult(m_nID, 0) == InspResult::Fail) continue; int lsPath = m_slot[i].getLinkSignalPath(); if(!m_bLinkSignalToUpstream[lsPath][SIGNAL_UPSTREAM_INLINE] || m_bLinkSignalToUpstream[lsPath][SIGNAL_UPSTREAM_TROUBLE] || !m_bLinkSignalToUpstream[lsPath][SIGNAL_INTERLOCK] || !m_bLinkSignalToUpstream[lsPath][SIGNAL_SEND_ABLE] ) continue; if (m_nTestFlag == 1) LOGD("getProcessedSlot 008"); MaterialsType glassType = pGlass->getType(); if (glassType == MaterialsType::G1 && putSlotType == MaterialsType::G2) continue; if (m_nTestFlag == 1) LOGD("getProcessedSlot 009"); if (glassType == MaterialsType::G2 && putSlotType == MaterialsType::G1) continue; if (m_nTestFlag == 1) LOGD("getProcessedSlot 00a"); return &m_slot[i]; } return nullptr; } CSlot* CEquipment::getProcessedSlot2(MaterialsType putSlotType, const std::vector& candidates) { for (auto item : candidates) { for (int i = 0; i < SLOT_MAX; i++) { if (item == i + 1) { if (!m_slot[i].isEnable()) continue; if (m_slot[i].isLock()) continue; CGlass* pGlass = (CGlass*)m_slot[i].getContext(); if (pGlass == nullptr) continue; if (!isSlotProcessed(i+1)) continue; int lsPath = m_slot[i].getLinkSignalPath(); if (!m_bLinkSignalToUpstream[lsPath][SIGNAL_UPSTREAM_INLINE] || m_bLinkSignalToUpstream[lsPath][SIGNAL_UPSTREAM_TROUBLE] || !m_bLinkSignalToUpstream[lsPath][SIGNAL_INTERLOCK] || !m_bLinkSignalToUpstream[lsPath][SIGNAL_SEND_ABLE]) continue; MaterialsType glassType = pGlass->getType(); if (glassType == MaterialsType::G1 && putSlotType == MaterialsType::G2) continue; if (glassType == MaterialsType::G2 && putSlotType == MaterialsType::G1) continue; return &m_slot[i]; } } } return nullptr; } CSlot* CEquipment::getProcessedSlotCt(unsigned int slot) { if (slot >= 8) return nullptr; if (!m_slot[slot].isEnable()) return nullptr; if (m_slot[slot].isLock()) return nullptr; CGlass* pGlass = (CGlass*)m_slot[slot].getContext(); if (pGlass == nullptr) return nullptr; int lsPath = m_slot[slot].getLinkSignalPath(); if (!m_bLinkSignalToUpstream[lsPath][SIGNAL_UPSTREAM_INLINE] || m_bLinkSignalToUpstream[lsPath][SIGNAL_UPSTREAM_TROUBLE] || !m_bLinkSignalToUpstream[lsPath][SIGNAL_INTERLOCK] || !m_bLinkSignalToUpstream[lsPath][SIGNAL_SEND_ABLE]) return nullptr; return &m_slot[slot]; } CSlot* CEquipment::getInspFailSlot() { for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; if (m_slot[i].isLock()) continue; CGlass* pGlass = (CGlass*)m_slot[i].getContext(); if (pGlass == nullptr) continue; if (!pGlass->isScheduledForProcessing()) continue; if (pGlass->getInspResult(m_nID, 0) != InspResult::Fail) continue; int lsPath = m_slot[i].getLinkSignalPath(); if (!m_bLinkSignalToUpstream[lsPath][SIGNAL_UPSTREAM_INLINE] || m_bLinkSignalToUpstream[lsPath][SIGNAL_UPSTREAM_TROUBLE] || !m_bLinkSignalToUpstream[lsPath][SIGNAL_INTERLOCK] || !m_bLinkSignalToUpstream[lsPath][SIGNAL_SEND_ABLE]) continue; return &m_slot[i]; } return nullptr; } CSlot* CEquipment::getSlot(int index) { if (index >= SLOT_MAX) return nullptr; return &m_slot[index]; } CSlot* CEquipment::getSlotWithNo(int slotNo) { CSlot* pSlot = nullptr; for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; if (m_slot[i].getNo() != slotNo) continue; pSlot = &m_slot[i]; break; } return pSlot; } CGlass* CEquipment::getAnyGlass() { CSlot* pSlot = nullptr; for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; CGlass* pGlass = (CGlass*)m_slot[i].getContext(); if (pGlass == nullptr) continue; return pGlass; } return nullptr; } BOOL CEquipment::canPlaceGlassInSlot(const short slotIndex) { if (slotIndex >= SLOT_MAX) return FALSE; if (!m_slot[slotIndex].isEnable()) return FALSE; if (m_slot[slotIndex].getContext() != nullptr) return FALSE; return TRUE; } BOOL CEquipment::slotHasGlass(int slotIndex/* = 0*/) { ASSERT(slotIndex < 8); CGlass* pGlass = (CGlass*)m_slot[slotIndex].getContext(); return (pGlass != nullptr); } int CEquipment::removeGlass(int slotNo) { CSlot* pSlot = nullptr; for (int i = 0; i < SLOT_MAX; i++) { if (!m_slot[i].isEnable()) continue; if (m_slot[i].getNo() != slotNo) continue; pSlot = &m_slot[i]; break; } if (pSlot == nullptr) return -1; pSlot->setContext(nullptr); if (m_listener.onDataChanged != nullptr) { m_listener.onDataChanged(this, EDCC_FETCHOUT_JOB); } return 0; } short CEquipment::decodeRecipeListReport(const char* pszData, size_t size) { return m_recipesManager.decodeRecipeListReport(pszData, size); } short CEquipment::decodeRecipeParameterReport(const char* pszData, size_t size) { return m_recipesManager.decodeRecipeParameterReport(pszData, size); } int CEquipment::decodeProcessDataReport(CStep* pStep, const char* pszData, size_t size) { CProcessData processData; int nRet = processData.unserialize(&pszData[0], (int)size); if (nRet < 0) return nRet; // 缓存Attribute,用于调试时显示信息 unsigned int weight = 201; CAttributeVector& attrubutes = pStep->attributeVector(); processData.getAttributeVector(attrubutes, weight); onProcessData(&processData); // 找到玻璃,关联数据 CGlass* pGlass = this->getGlassWithCassette(processData.getCassetteSequenceNo(), processData.getJobSequenceNo()); if (pGlass == nullptr) { LOGE("找不到对应Glass, 关联工艺参数失败。CassetteSequenceNo:%d/%d", this->getName().c_str(), processData.getCassetteSequenceNo(), processData.getJobSequenceNo()); return -1; } auto rawData = processData.getParamsRawData(); std::vector tempParams; this->parsingProcessData((const char*)rawData.data(), rawData.size(), tempParams); int n = processData.getTotalParameter(); std::vector params(tempParams.begin(), tempParams.begin() + (std::min)(n, (int)tempParams.size())); pGlass->addParams(params); if (m_listener.onProcessDataReport != nullptr) { m_listener.onProcessDataReport(this, params); } // 关联的Glass也要更新 CGlass* pBuddy = pGlass->getBuddy(); LOGI("decodeProcessDataReport pBuddy=%x %s", getName().c_str(), pBuddy, pGlass->getID().c_str()); if (pBuddy != nullptr) { LOGI("decodeProcessDataReport addParams pBuddy=%x %s", getName().c_str(), pBuddy, pGlass->getID().c_str()); pBuddy->addParams(params); if (m_listener.onProcessDataReport != nullptr) { m_listener.onProcessDataReport(this, params); } } return nRet; } int CEquipment::decodeReceivedJobReport(CStep* pStep, int port, const char* pszData, size_t size) { CJobDataS jobDataS; int nRet = jobDataS.unserialize(&pszData[0], (int)size); if (nRet < 0) return nRet; // 缓存Attribute,用于调试时显示信息 unsigned int weight = 201; CAttributeVector& attrubutes = pStep->attributeVector(); jobDataS.getAttributeVector(attrubutes, weight); onReceivedJob(port, &jobDataS); return nRet; } int CEquipment::onReceivedJob(int port, CJobDataS* pJobDataS) { LOGI("onReceivedJob.", m_strName.c_str()); // 可以在此更新JobDataS数据了 int nRet = ((CArm*)m_pArm)->glassUpdateJobDataS(pJobDataS); if (nRet < 0) { LOGE("onReceivedJob,更新JobDataS失败,glassUpdateJobDataS返回%d", m_strName.c_str(), nRet); } if (m_listener.onReceivedJob != nullptr) { m_listener.onReceivedJob(this, port, pJobDataS); } return nRet; } int CEquipment::decodeSentOutJobReport(CStep* pStep, int port, const char* pszData, size_t size) { CJobDataS jobDataS; int nRet = jobDataS.unserialize(&pszData[0], (int)size); if (nRet < 0) return nRet; // 缓存Attribute,用于调试时显示信息 unsigned int weight = 201; CAttributeVector& attrubutes = pStep->attributeVector(); jobDataS.getAttributeVector(attrubutes, weight); onSentOutJob(port, &jobDataS); return nRet; } int CEquipment::onSentOutJob(int port, CJobDataS* pJobDataS) { LOGI("onSentOutJob.", m_strName.c_str()); if (m_listener.onSentOutJob != nullptr) { m_listener.onSentOutJob(this, port, pJobDataS); } return 0; } int CEquipment::decodeFetchedOutJobReport(CStep* pStep, int port, const char* pszData, size_t size) { int index = 0; short unitOrPort, unitOrPortNo, subUnitNo, subSlotNo; CJobDataB jobDataB; int nRet = jobDataB.unserialize(&pszData[index], (int)size); if (nRet < 0) return nRet; index += nRet; memcpy(&unitOrPort, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&unitOrPortNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&subUnitNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&subSlotNo, &pszData[index], sizeof(short)); index += sizeof(short); // 缓存Attribute,用于调试时显示信息 unsigned int weight = 201; pStep->addAttribute(new CAttribute("UnitOrPort", std::to_string(unitOrPort).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("UnitOrPortNo", std::to_string(unitOrPortNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("SubUnitNo", std::to_string(subUnitNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("SubSlotNo", std::to_string(subSlotNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("CassetteSequenceNo", std::to_string(jobDataB.getCassetteSequenceNo()).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("JobSequenceNo", std::to_string(jobDataB.getJobSequenceNo()).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("GlassId", jobDataB.getGlassId().c_str(), "", weight++)); onFetchedOutJob(port, &jobDataB); return index; } BOOL CEquipment::onPreFetchedOutJob(int port, CJobDataB* pJobDataB) { LOGI("onPreFetchedOutJob:port:%d|GlassId:%s", m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); if (m_listener.onPreFethedOutJob != nullptr) { return m_listener.onPreFethedOutJob(this, port, pJobDataB); } return TRUE; } int CEquipment::onFetchedOutJob(int port, CJobDataB* pJobDataB) { LOGI("onFetchedOutJob:port:%d|GlassId:%s", m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); BOOL bCheck = onPreFetchedOutJob(port, pJobDataB); if (bCheck) { return fetchedOutJob(port, pJobDataB); } // 数据异常,处理或显示 LOGI("onFetchedOutJob Error.ort:%d|GlassId:%s", m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); return -1; } int CEquipment::decodeStoredJobReport(CStep* pStep, int port, const char* pszData, size_t size) { int index = 0; short unitOrPort, unitOrPortNo, subUnitNo, subSlotNo; CJobDataB jobDataB; int nRet = jobDataB.unserialize(&pszData[index], (int)size); if (nRet < 0) return nRet; index += nRet; memcpy(&unitOrPort, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&unitOrPortNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&subUnitNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&subSlotNo, &pszData[index], sizeof(short)); index += sizeof(short); // 缓存Attribute,用于调试时显示信息 unsigned int weight = 201; pStep->addAttribute(new CAttribute("UnitOrPort", std::to_string(unitOrPort).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("UnitOrPortNo", std::to_string(unitOrPortNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("SubUnitNo", std::to_string(subUnitNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("SubSlotNo", std::to_string(subSlotNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("CassetteSequenceNo", std::to_string(jobDataB.getCassetteSequenceNo()).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("JobSequenceNo", std::to_string(jobDataB.getJobSequenceNo()).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("GlassId", jobDataB.getGlassId().c_str(), "", weight++)); onStoredJob(port, &jobDataB); return index; } int CEquipment::decodeVCREventReport(CStep* pStep, const char* pszData, size_t size) { CVcrEventReport vcrEventReport; vcrEventReport.unserialize(pszData, (int)size); LOGI("decodeVCREventReport\n", m_strName.c_str(), vcrEventReport.getVcrResult(), vcrEventReport.getGlassId().c_str()); // 更新Glass的ID CGlass* pGlass = getGlassWithCassette(vcrEventReport.getCassetteSequenceNo(), vcrEventReport.getJobSequenceNo()); if (pGlass != nullptr) { pGlass->setID(vcrEventReport.getGlassId().c_str()); } // 缓存Attribute,用于调试时显示信息 unsigned int weight = 201; CAttributeVector& attrubutes = pStep->attributeVector(); vcrEventReport.getAttributeVector(attrubutes, weight); // 0426, 先固定返回1(OK) ((CReadStep*)pStep)->setReturnCode((short)VCR_Reply_Code::OK); return 0; } int CEquipment::decodePanelDataReport(CStep* pStep, const char* pszData, size_t size) { short cassetteNo, jobSequenceNo; int index = 0; std::string strPanelJudgeData, strPanelGradeData; memcpy(&cassetteNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&jobSequenceNo, &pszData[index], sizeof(short)); index += sizeof(short); CToolUnits::convertString(&pszData[index], 128 * 2, strPanelJudgeData); index += 128 * 2; CToolUnits::convertString(&pszData[index], 256 * 2, strPanelGradeData); index += 256 * 2; // 缓存Attribute,用于调试时显示信息 unsigned int weight = 201; pStep->addAttribute(new CAttribute("CassetteNo", std::to_string(cassetteNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("JobSequenceNo", std::to_string(jobSequenceNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("PanelJudgeData", strPanelJudgeData.c_str(), "", weight++)); pStep->addAttribute(new CAttribute("PanelGradeData", strPanelGradeData.c_str(), "", weight++)); // 更新检测结果 CGlass* pGlass = getGlassWithCassette(cassetteNo, jobSequenceNo); if (pGlass == nullptr) { LOGE("更新Panel Data失败,找不到对应的Glass.cassetteNo=%d, jobSequenceNo=%d", getName().c_str(), cassetteNo, jobSequenceNo); return -1; } auto result = judgeStringToInspResult(strPanelJudgeData); pGlass->setInspResult(m_nID, 0, result); if (m_listener.onPanelDataReport != nullptr) { m_listener.onPanelDataReport(this, pGlass); } return 0; } int CEquipment::decodeFacDataReport(CStep* pStep, const char* pszData, size_t size) { CSVData svData; int nRet = svData.unserialize(&pszData[0], (int)size); if (nRet < 0) return nRet; Lock(); m_svDatas.push_back(svData); Unlock(); if (m_listener.onSVDataReport != nullptr) { m_listener.onSVDataReport(this, &svData); } return 0; } int CEquipment::decodeJobDataRequest(CStep* pStep, const char* pszData, size_t size) { int index = 0; short cassetteSequenceNo, jobSequenceNo; memcpy(&cassetteSequenceNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&jobSequenceNo, &pszData[index], sizeof(short)); index += sizeof(short); cassetteSequenceNo = 4000; jobSequenceNo = 1; // 缓存Attribute,用于调试时显示信息 unsigned int weight = 201; pStep->addAttribute(new CAttribute("CassetteSequenceNo", (std::to_string(cassetteSequenceNo)).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("JobSequenceNo", (std::to_string(jobSequenceNo)).c_str(), "", weight++)); return 0; } int CEquipment::decodeJobProcessStartReport(CStep* pStep, const char* pszData, size_t size) { int port = (int)(__int64)pStep->getProp("Port"); LOGI("decodeJobProcessStartReport, port:%d", getName().c_str(), port); short cassetteNo, jobSequenceNo, unitNo, subUnitNo, slotNo; int year, month, day, hour, minute, second; int index = 0; memcpy(&cassetteNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&jobSequenceNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&unitNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&subUnitNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&slotNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&year, &pszData[index], sizeof(short)); index += sizeof(short); month = (int)pszData[index]; index += 1; day = (int)pszData[index]; index += 1; hour = (int)pszData[index]; index += 1; minute = (int)pszData[index]; index += 1; second = (int)pszData[index]; index += 1; LOGI("cassetteNo:%d, jobSequenceNo:%d,unitNo:%d, subUnitNo:%d, slotNo:%d %d-%d-%d %d:%d:%d", getName().c_str(), cassetteNo, jobSequenceNo, unitNo, subUnitNo, slotNo, year, month, day, hour, minute, second ); CGlass* pGlass = getGlassFromSlot(slotNo); if (pGlass == nullptr) { LOGE("decodeJobProcessStartReport, 找不到对应glass", getName().c_str()); } if (slotNo <= 0 || slotNo > 8) return -1; if (m_processState[slotNo -1] != PROCESS_STATE::Processing) { Lock(); m_svDatas.clear(); Unlock(); setProcessState(slotNo, PROCESS_STATE::Processing); } // 缓存Attribute,用于调试时显示信息 unsigned int weight = 201; pStep->addAttribute(new CAttribute("CassetteNo", std::to_string(cassetteNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("JobSequenceNo", std::to_string(jobSequenceNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("UnitNo", std::to_string(unitNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("SubUnitNo", std::to_string(subUnitNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("SlotNo", std::to_string(slotNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("ProcessStartTime", (std::to_string(year) + std::to_string(day) + std::to_string(day) + std::to_string(hour) + std::to_string(minute) + std::to_string(second)).c_str() , "", weight++)); return 0; } int CEquipment::decodeJobProcessEndReport(CStep* pStep, const char* pszData, size_t size) { int port = (int)(__int64)pStep->getProp("Port"); LOGI("decodeJobProcessEndReport, port:%d", getName().c_str(), port); short cassetteNo, jobSequenceNo, unitNo, subUnitNo, slotNo; int year, month, day, hour, minute, second; int index = 0; std::string strPanelJudgeData, strPanelGradeData; memcpy(&cassetteNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&jobSequenceNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&unitNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&subUnitNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&slotNo, &pszData[index], sizeof(short)); index += sizeof(short); memcpy(&year, &pszData[index], sizeof(short)); index += sizeof(short); month = (int)pszData[index]; index += 1; day = (int)pszData[index]; index += 1; hour = (int)pszData[index]; index += 1; minute = (int)pszData[index]; index += 1; second = (int)pszData[index]; index += 1; LOGI("cassetteNo:%d, jobSequenceNo:%d,unitNo:%d, subUnitNo:%d, slotNo:%d %d-%d-%d %d:%d:%d", getName().c_str(), cassetteNo, jobSequenceNo, unitNo, subUnitNo, slotNo, year, month, day, hour, minute, second ); CGlass* pGlass = getGlassFromSlot(slotNo); if (m_processState[slotNo - 1] != PROCESS_STATE::Complete) { setProcessState(slotNo, PROCESS_STATE::Complete); } if (pGlass == nullptr) { LOGE("decodeJobProcessEndReport, 找不到对应glass", getName().c_str()); } else { CJobDataS* pJs = pGlass->getJobDataS(); if (pJs->getCassetteSequenceNo() == cassetteNo && pJs->getJobSequenceNo() == jobSequenceNo) { pGlass->processEnd(m_nID, getSlotUnit(slotNo)); } else { LOGE("decodeJobProcessEndReport, jobSequenceNo或jobSequenceNo不匹配", getName().c_str()); } } // 缓存Attribute,用于调试时显示信息 unsigned int weight = 201; pStep->addAttribute(new CAttribute("CassetteNo", std::to_string(cassetteNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("JobSequenceNo", std::to_string(jobSequenceNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("UnitNo", std::to_string(unitNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("SubUnitNo", std::to_string(subUnitNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("SlotNo", std::to_string(slotNo).c_str(), "", weight++)); pStep->addAttribute(new CAttribute("ProcessStartTime", (std::to_string(year) + std::to_string(day) + std::to_string(day) + std::to_string(hour) + std::to_string(minute) + std::to_string(second)).c_str() , "", weight++)); return 0; } int CEquipment::onPreStoredJob(int port, CJobDataB* pJobDataB, short& putSlot) { LOGI("onPreStoredJob:port:%d|GlassId:%s", m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); // 当前要存片,之前肯定有拔片,因此片子在Arm那里 CGlass* pGlass = ((CArm*)m_pArm)->getGlassFromSlot(1); if (pGlass == nullptr) { LOGE("onPreStoredJob,缓存中没有找到对应的Glass(CassetteSequenceNo:%d, JobSequenceNo:%d),请检查数据,注意风险。", m_strName.c_str(), pJobDataB->getCassetteSequenceNo(), pJobDataB->getJobSequenceNo()); return FALSE; } CJobDataS* pJobDataS = pGlass->getJobDataS(); ASSERT(pJobDataS); if (!compareJobData(pJobDataB, pJobDataS)) { LOGE("onPreStoredJob,JobData数据不匹配(JobDataB(%d, %d),JobDataS(%d, %d)), 注意排查风险!", m_strName.c_str(), pJobDataB->getCassetteSequenceNo(), pJobDataB->getJobSequenceNo(), pJobDataS->getCassetteSequenceNo(), pJobDataS->getJobSequenceNo()); return FALSE; } // 如果没有可用位置,报错 Lock(); CSlot* pSlot = getSlot(putSlot - 1); ASSERT(pSlot); if (pSlot->getContext() != nullptr) { Unlock(); LOGE("onPreStoredJob,指定slot(port:%d)有料,请注意风险!", m_strName.c_str(), port); return FALSE; } Unlock(); if (m_listener.onPreStoredJob != nullptr) { if (!m_listener.onPreStoredJob(this, port, pJobDataB, putSlot)) { return FALSE; } if(!canPlaceGlassInSlot(putSlot - 1)) { return FALSE; } } return TRUE; } int CEquipment::onStoredJob(int port, CJobDataB* pJobDataB) { LOGI("onStore:port:%d|GlassId:%s", m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); short putSlot = 0; BOOL bCheck = onPreStoredJob(port, pJobDataB, putSlot); if (bCheck) { return storedJob(port, pJobDataB, putSlot); } // 数据异常,处理或显示 LOGI("onStoredJob Error.port:%d|GlassId:%s", m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); return -1; } int CEquipment::onProcessData(CProcessData* pProcessData) { LOGI("onProcessData.", m_strName.c_str()); return 0; } /* * 当从CC-Link检测到设备Send Able为On时调用此函数 * 可能会多次重复调用(根据扫描频率), 注意防呆 */ int CEquipment::onSendAble(int port) { // LOGI("onSendAble.port:%d", m_strName.c_str(), port); return 0; } int CEquipment::onReceiveAble(int port) { // LOGI("onReceiveAble.port:%d", m_strName.c_str(), port); return 0; } int CEquipment::onProcessStateChanged(int nSlotNo, PROCESS_STATE prevState, PROCESS_STATE state) { return 0; } int CEquipment::getIndexerOperationModeBaseValue() { return 0; } BOOL CEquipment::compareJobData(CJobDataB* pJobDataB, CJobDataS* pJobDataS) { ASSERT(pJobDataB); ASSERT(pJobDataS); if (pJobDataB->getCassetteSequenceNo() != pJobDataS->getCassetteSequenceNo()) return FALSE; if (pJobDataB->getJobSequenceNo() != pJobDataS->getJobSequenceNo()) return FALSE; return TRUE; } void CEquipment::printDebugString001() { for (int i = 0; i < 8; i++) { LOGI("Link Signal to UP stream Path#%d, Signal:%s, %s, %s, %s", m_strName.c_str(), i, m_bLinkSignalToUpstream[i][SIGNAL_UPSTREAM_INLINE] ? "ON" : "OFF", m_bLinkSignalToUpstream[i][SIGNAL_UPSTREAM_TROUBLE] ? "ON" : "OFF", m_bLinkSignalToUpstream[i][SIGNAL_INTERLOCK] ? "ON" : "OFF", m_bLinkSignalToUpstream[i][SIGNAL_SEND_ABLE] ? "ON" : "OFF" ); } for (int i = 0; i < 8; i++) { LOGI("Link Signal to Down stream Path#%d, Signal:%s, %s, %s, %s", m_strName.c_str(), i, m_bLinkSignalToDownstream[i][SIGNAL_UPSTREAM_INLINE] ? "ON" : "OFF", m_bLinkSignalToDownstream[i][SIGNAL_UPSTREAM_TROUBLE] ? "ON" : "OFF", m_bLinkSignalToDownstream[i][SIGNAL_INTERLOCK] ? "ON" : "OFF", m_bLinkSignalToDownstream[i][SIGNAL_SEND_ABLE] ? "ON" : "OFF" ); } } InspResult CEquipment::judgeStringToInspResult(std::string& strJudge) { if (strJudge.compare("N") == 0) { return InspResult::Fail; } if (strJudge.compare("G") == 0) { return InspResult::Pass; } return InspResult::NotInspected; } float CEquipment::toFloat(const char* pszAddr) { BYTE szBuffer[4]; szBuffer[0] = pszAddr[0]; szBuffer[1] = pszAddr[1]; szBuffer[2] = pszAddr[2]; szBuffer[3] = pszAddr[3]; float f = 0.0; memcpy(&f, szBuffer, 4); return f; } int CEquipment::parsingParams(const char* pszData, size_t size, std::string& strOut) { std::vector params; int nRet = parsingParams(pszData, size, params); if (nRet <= 0) return nRet; char szBuffer[256]; for (auto p : params) { if(!strOut.empty()) strOut.append(","); if (p.getValueType() == PVT_INT) { sprintf_s(szBuffer, 256, "%s:%d", p.getName().c_str(), p.getIntValue()); } else if (p.getValueType() == PVT_DOUBLE) { sprintf_s(szBuffer, 256, "%s:%f", p.getName().c_str(), p.getDoubleValue()); } strOut.append(szBuffer); } return 0; }; void CEquipment::addFacDataReportStep(int dataDev, int writeSignalDev, int port) { CEqReadStep* pStep = new CEqReadStep(dataDev, 133 * 2, [&](void* pFrom, int code, const char* pszData, size_t size) -> int { if (code == ROK && pszData != nullptr && size > 0) { decodeFacDataReport((CStep*)pFrom, pszData, size); } return -1; }); pStep->setName(STEP_EQ_FAC_DATA_REPORT); pStep->setProp("Port", (void*)(__int64)port); pStep->setReadContinue(TRUE); pStep->setWriteSignalDev(writeSignalDev); if (addStep(STEP_ID_FAC_DATA_REPORT, pStep) != 0) { delete pStep; } } std::vector& CEquipment::getSVDatas() { return m_svDatas; } }