1.一些输出日志信息,更新等级;
2.CPath增加Slot信息;
3.WIP数据显示到列表控件;
4.调整Glass的Path信息文本输出;
已修改35个文件
518 ■■■■ 文件已修改
SourceCode/Bond/Servo/CAligner.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CBakeCooling.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEFEM.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqAlarmStep.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqJobEventStep.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqPortChangeStep.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqProcessStep.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqReadIntStep.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqReadStep.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqStatusStep.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEqVcrEventStep.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.cpp 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipmentPage3.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CFliper.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CGlass.cpp 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CGlass.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CLoadPort.cpp 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageCassetteCtrlCmd.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGlassList.cpp 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGlassList.h 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPath.cpp 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPath.h 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CRobotTask.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CServoUtilsTool.cpp 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CServoUtilsTool.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/DevicePropertyDlg.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/GlassJson.cpp 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ListCtrlEx.cpp 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.cpp 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ToolUnits.cpp 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ToolUnits.h 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/resource.h 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CAligner.cpp
@@ -32,7 +32,7 @@
    void CAligner::initPins()
    {
        // 加入Pin初始化代码
        LOGI("<CAligner>initPins");
        LOGD("<CAligner>initPins");
        addPin(SERVO::PinType::INPUT, _T("In1"));
        addPin(SERVO::PinType::INPUT, _T("In2"));
        addPin(SERVO::PinType::OUTPUT, _T("Out1"));
SourceCode/Bond/Servo/CBakeCooling.cpp
@@ -32,7 +32,7 @@
    void CBakeCooling::initPins()
    {
        // 加入Pin初始化代码
        LOGI("<CBakeCooling>initPins");
        LOGD("<CBakeCooling>initPins");
        addPin(SERVO::PinType::INPUT, _T("In1"));
        addPin(SERVO::PinType::INPUT, _T("In2"));
        addPin(SERVO::PinType::OUTPUT, _T("Out"));
SourceCode/Bond/Servo/CEFEM.cpp
@@ -133,7 +133,7 @@
                    LOGI("<CEquipment-%s>发送RobotCmdS成功.", m_strName.c_str());
                }
                else {
                    LOGI("<CEquipment-%s>发送RobotCmds失败,code:%d", m_strName.c_str(), code);
                    LOGE("<CEquipment-%s>发送RobotCmds失败,code:%d", m_strName.c_str(), code);
                }
                return 0;
@@ -367,7 +367,7 @@
    void CEFEM::initPins()
    {
        // 加入Pin初始化代码
        LOGI("<CEFEM>initPins");
        LOGD("<CEFEM>initPins");
    }
    void CEFEM::initSteps()
@@ -874,7 +874,7 @@
    void CEFEM::printDebugRobotState()
    {
        LOGI("<CEFEM>Robot status:%d, ARM1:%s, ARM2:%s",
        LOGD("<CEFEM>Robot status:%d, ARM1:%s, ARM2:%s",
            m_robotData.status,
            m_robotData.armState[0] ? _T("ON") : _T("OFF"),
            m_robotData.armState[1] ? _T("ON") : _T("OFF"));
SourceCode/Bond/Servo/CEqAlarmStep.cpp
@@ -58,7 +58,7 @@
        m_nAlarmCode = (unsigned int)CToolUnits::toInt16(&szBuffer[6]);
        m_nAlarmLevel = (unsigned int)CToolUnits::toInt16(&szBuffer[8]);
        LOGI("<CEqAlarmStep> Equipment Alarm state Changed<State:%d, Unit:%d, Level:%d, Code:%d, ID:%d>",
        LOGE("<CEqAlarmStep> Equipment Alarm state Changed<State:%d, Unit:%d, Level:%d, Code:%d, ID:%d>",
            m_nAlarmState, m_nUnitId, m_nAlarmLevel, m_nAlarmCode, m_nAlarmId,
            m_strText.c_str(), m_strDescription.c_str());
@@ -68,7 +68,7 @@
    int CEqAlarmStep::onComplete()
    {
        CReadStep::onComplete();
        LOGI("<CEqAlarmStep> onComplete.");
        LOGD("<CEqAlarmStep> onComplete.");
        return 0;
    }
@@ -76,7 +76,7 @@
    int CEqAlarmStep::onTimeout()
    {
        CReadStep::onTimeout();
        LOGI("<CEqAlarmStep> onTimeout.");
        LOGE("<CEqAlarmStep> onTimeout.");
        return 0;
    }
SourceCode/Bond/Servo/CEqJobEventStep.cpp
@@ -57,7 +57,7 @@
    int CEqJobEventStep::onTimeout()
    {
        CReadStep::onTimeout();
        LOGI("<CEqJobEventStep> onTimeout.");
        LOGE("<CEqJobEventStep> onTimeout.");
        return 0;
    }
SourceCode/Bond/Servo/CEqPortChangeStep.cpp
@@ -80,7 +80,7 @@
    int CEqPortChangeStep::onTimeout()
    {
        CReadStep::onTimeout();
        LOGI("<CEQPortChangeStep> onTimeout.");
        LOGE("<CEQPortChangeStep> onTimeout.");
        return 0;
    }
SourceCode/Bond/Servo/CEqProcessStep.cpp
@@ -119,7 +119,7 @@
    int CEqProcessStep::onTimeout()
    {
        CReadStep::onTimeout();
        LOGI("<CEqProcessStep> onTimeout.");
        LOGE("<CEqProcessStep> onTimeout.");
        return 0;
    }
SourceCode/Bond/Servo/CEqReadIntStep.cpp
@@ -71,7 +71,7 @@
    int CEqReadIntStep::onTimeout()
    {
        CReadStep::onTimeout();
        LOGI("<CEqReadIntStep> onTimeout.");
        LOGE("<CEqReadIntStep> onTimeout.");
        return 0;
    }
SourceCode/Bond/Servo/CEqReadStep.cpp
@@ -53,14 +53,14 @@
        int nRet = m_pCclink->ReadData2(m_station, DeviceType::W, m_nDataDev,
            (long)min(READ_BUFFER_MAX, m_nReadSize), szBuffer);
        if (0 != nRet) {
            LOGI("<CEqReadStep>Read data error.");
            LOGE("<CEqReadStep>Read data error.");
            if (m_onReadBlock != nullptr) {
                m_onReadBlock(this, RERROR, nullptr, 0);
            }
            return -1;
        }
        LOGI("<CEqReadStep>read data succeed.");
        LOGD("<CEqReadStep>read data succeed.");
        if (m_onReadBlock != nullptr) {
            m_onReadBlock(this, ROK, szBuffer, m_nReadSize);
        }
@@ -72,7 +72,7 @@
    int CEqReadStep::onComplete()
    {
        CReadStep::onComplete();
        LOGI("<CEqReadStep> onComplete.");
        LOGD("<CEqReadStep> onComplete.");
        if (m_onReadBlock != nullptr) {
            m_onReadBlock(this, RCOMPLETE, nullptr, 0);
        }
@@ -83,7 +83,7 @@
    int CEqReadStep::onTimeout()
    {
        CReadStep::onTimeout();
        LOGI("<CEqReadStep> onTimeout.");
        LOGE("<CEqReadStep> onTimeout.");
        if (m_onReadBlock != nullptr) {
            m_onReadBlock(this, RTIMEOUT, nullptr, 0);
        }
SourceCode/Bond/Servo/CEqStatusStep.cpp
@@ -93,7 +93,7 @@
    int CEqStatusStep::onTimeout()
    {
        CReadStep::onTimeout();
        LOGI("<CEqStatusStep> onTimeout.");
        LOGE("<CEqStatusStep> onTimeout.");
        return 0;
    }
SourceCode/Bond/Servo/CEqVcrEventStep.cpp
@@ -70,7 +70,7 @@
    int CEqVcrEventStep::onTimeout()
    {
        CReadStep::onTimeout();
        LOGI("<CEqVcrEventStep> onTimeout.");
        LOGE("<CEqVcrEventStep> onTimeout.");
        return 0;
    }
SourceCode/Bond/Servo/CEquipment.cpp
@@ -839,7 +839,7 @@
        CEquipment* pFromEq = pFromPin->getEquipment();
        ASSERT(pFromEq);
        LOGI("<CEquipment><%s-%s>收到来自<%s.%s>的Intent<%d,%s,0x%x>",
        LOGD("<CEquipment><%s-%s>收到来自<%s.%s>的Intent<%d,%s,0x%x>",
            this->getName().c_str(),
            pPin->getName().c_str(),
            pFromEq->getName().c_str(),
@@ -916,7 +916,7 @@
        ASSERT(pGlass);
        Lock();
        pGlass->addPath(m_nID, getSlotUnit(putSlot));
        pGlass->addPath(m_nID, getSlotUnit(putSlot), putSlot);
        m_slot[putSlot - 1].setContext(pGlass);
        pGlass->release();                // tempFetchOut需要调用一次release
        Unlock();
@@ -990,6 +990,22 @@
        return nullptr;
    }
    int CEquipment::getAllGlass(std::vector<CGlass*>& 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)
@@ -1138,7 +1154,7 @@
                    LOGI("<CEquipment-%s>设置DispatchingMode成功.", m_strName.c_str());
                }
                else {
                    LOGI("<CEquipment-%s>设置DispatchingMode失败,code:%d", m_strName.c_str(), code);
                    LOGE("<CEquipment-%s>设置DispatchingMode失败,code:%d", m_strName.c_str(), code);
                }
                return 0;
@@ -1168,7 +1184,7 @@
                LOGI("<CEquipment-%s>返回值: %d", m_strName.c_str(), retCode);
            }
            else {
                LOGI("<CEquipment-%s>设置indexerOperationMode失败,code:%d", m_strName.c_str(), code);
                LOGE("<CEquipment-%s>设置indexerOperationMode失败,code:%d", m_strName.c_str(), code);
            }
            if (onWritedRetBlock != nullptr) {
@@ -1199,7 +1215,7 @@
            }
            else {
                m_recipesManager.syncFailed();
                LOGI("<CEquipment-%s>请求单元<%d>主配方列表失败,code:%d", m_strName.c_str(), unitNo, code);
                LOGE("<CEquipment-%s>请求单元<%d>主配方列表失败,code:%d", m_strName.c_str(), unitNo, code);
            }
            return 0;
@@ -1234,7 +1250,7 @@
            }
            else {
                m_recipesManager.syncFailed();
                LOGI("<CEquipment-%s>请求单元<%d>主配方参数列表失败,code:%d", m_strName.c_str(), unitNo, code);
                LOGE("<CEquipment-%s>请求单元<%d>主配方参数列表失败,code:%d", m_strName.c_str(), unitNo, code);
            }
            return 0;
@@ -1358,32 +1374,32 @@
    CSlot* CEquipment::getProcessedSlot(MaterialsType putSlotType, BOOL bJobMode/* = FALSE*/)
    {
        for (int i = 0; i < SLOT_MAX; i++) {
            if (m_nTestFlag == 1) LOGI("getProcessedSlot 001");
            if (m_nTestFlag == 1) LOGD("getProcessedSlot 001");
            if (!m_slot[i].isEnable()) continue;
            if (m_nTestFlag == 1) LOGI("getProcessedSlot 002");
            if (m_nTestFlag == 1) LOGD("getProcessedSlot 002");
            if (m_slot[i].isLock()) continue;
            if (m_nTestFlag == 1) LOGI("getProcessedSlot 003");
            if (m_nTestFlag == 1) LOGD("getProcessedSlot 003");
            CGlass* pGlass = (CGlass*)m_slot[i].getContext();
            if (!isSlotProcessed(i)) continue;
            if (m_nTestFlag == 1) LOGI("getProcessedSlot 004");
            if (m_nTestFlag == 1) LOGD("getProcessedSlot 004");
            if (pGlass == nullptr) continue;
            if (m_nTestFlag == 1) LOGI("getProcessedSlot 005");
            if (m_nTestFlag == 1) LOGD("getProcessedSlot 005");
            if (!pGlass->isScheduledForProcessing()) continue;
            if (m_nTestFlag == 1) LOGI("getProcessedSlot 006");
            if (m_nTestFlag == 1) LOGD("getProcessedSlot 006");
            if (bJobMode && pGlass->getProcessJob() == nullptr) continue;
            if (m_nTestFlag == 1) LOGI("getProcessedSlot 007");
            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) LOGI("getProcessedSlot 008");
            if (m_nTestFlag == 1) LOGD("getProcessedSlot 008");
            MaterialsType glassType = pGlass->getType();
            if (glassType == MaterialsType::G1 && putSlotType == MaterialsType::G2) continue;
            if (m_nTestFlag == 1) LOGI("getProcessedSlot 009");
            if (m_nTestFlag == 1) LOGD("getProcessedSlot 009");
            if (glassType == MaterialsType::G2 && putSlotType == MaterialsType::G1) continue;
            if (m_nTestFlag == 1) LOGI("getProcessedSlot 00a");
            if (m_nTestFlag == 1) LOGD("getProcessedSlot 00a");
            return &m_slot[i];
        }
SourceCode/Bond/Servo/CEquipment.h
@@ -206,6 +206,7 @@
        CGlass* getGlassWithCassette(int cassetteSequenceNo, int jobSequenceNo);
        CGlass* getAnyGlass();
        CGlass* getGlass(const char* pszGlassId);
        int getAllGlass(std::vector<CGlass*>& glasses);
        CJobDataS* getJobDataSWithCassette(int cassetteSequenceNo, int jobSequenceNo);
        // 验证玻璃和槽是否匹配
SourceCode/Bond/Servo/CEquipmentPage3.cpp
@@ -91,7 +91,7 @@
                AfxMessageBox("设置EAS模式成功!");
            }
            else {
                LOGI("<CEquipment-%s>设置DispatchingMode失败,code:%d", m_pEquipment->getName().c_str(), code);
                LOGE("<CEquipment-%s>设置DispatchingMode失败,code:%d", m_pEquipment->getName().c_str(), code);
                AfxMessageBox("设置EAS模式失败!");
            }
SourceCode/Bond/Servo/CFliper.cpp
@@ -32,7 +32,7 @@
    void CFliper::initPins()
    {
        // 加入Pin初始化代码
        LOGI("<CFliper>initPins");
        LOGD("<CFliper>initPins");
        addPin(SERVO::PinType::INPUT, _T("In"));
        addPin(SERVO::PinType::OUTPUT, _T("Out1"));
        addPin(SERVO::PinType::OUTPUT, _T("Out2"));
SourceCode/Bond/Servo/CGlass.cpp
@@ -115,12 +115,12 @@
        CPath* pTemp = m_pPath;
        while (pTemp != nullptr) {
            pTemp->getSimpleDescription(strPath);
            strOut.append(strPath);
            if (strPath.compare("ARM1") != 0 && strPath.compare("ARM2") != 0) {
                if (!strOut.empty()) strOut.append(" -> ");
                strOut.append(strPath);
            }
            pTemp = pTemp->getNext();
            if (pTemp != nullptr) {
                strOut.append(" -> ");
            }
        }
        return strOut;
@@ -140,9 +140,9 @@
        return nullptr;
    }
    void CGlass::addPath(unsigned int nEqId, unsigned int nUnit)
    void CGlass::addPath(unsigned int nEqId, unsigned int nUnit, unsigned int slot)
    {
        CPath* pPath = new CPath(nEqId, nUnit);
        CPath* pPath = new CPath(nEqId, nUnit, slot);
        if (m_pPath == nullptr) {
            m_pPath = pPath;
        }
SourceCode/Bond/Servo/CGlass.h
@@ -47,7 +47,7 @@
        void setProcessJob(CProcessJob* pProcessJob);
        CPath* getPathWithEq(unsigned int nEqId, unsigned int nUnit) const;
        CPath* getPath();
        void addPath(unsigned int nEqId, unsigned int nUnit);
        void addPath(unsigned int nEqId, unsigned int nUnit, unsigned int slot);
        std::string getPathDescription() const;
        std::string getParamsDescription() const;
        void serialize(CArchive& ar);
SourceCode/Bond/Servo/CLoadPort.cpp
@@ -44,7 +44,7 @@
    void CLoadPort::initPins()
    {
        // 加入Pin初始化代码
        LOGI("<CLoadPort>initPins");
        LOGD("<CLoadPort>initPins");
        addPin(SERVO::PinType::INPUT, _T("In"));
        addPin(SERVO::PinType::OUTPUT, _T("Out"));
    }
@@ -983,7 +983,7 @@
                LOGI("<CLoadPort-%d>设置Port type成功.", m_nIndex);
            }
            else {
                LOGI("<CLoadPort-%d>设置Port type失败,code:%d", m_nIndex, code);
                LOGE("<CLoadPort-%d>设置Port type失败,code:%d", m_nIndex, code);
            }
            if (onWritedBlock != nullptr) {
                return onWritedBlock(code);
@@ -1013,7 +1013,7 @@
                LOGI("<CLoadPort-%d>%s Port成功.", m_nIndex, bEnable ? _T("启用") : _T("禁用"));
            }
            else {
                LOGI("<CLoadPort-%d>%s  Port失败,code:%d", m_nIndex, bEnable ? _T("启用") : _T("禁用"), code);
                LOGE("<CLoadPort-%d>%s  Port失败,code:%d", m_nIndex, bEnable ? _T("启用") : _T("禁用"), code);
            }
            if (onWritedBlock != nullptr) {
                return onWritedBlock(code);
@@ -1042,7 +1042,7 @@
                LOGI("<CLoadPort-%d>设置Port mode成功.", m_nIndex);
            }
            else {
                LOGI("<CLoadPort-%d>设置Port mode失败,code:%d", m_nIndex, code);
                LOGE("<CLoadPort-%d>设置Port mode失败,code:%d", m_nIndex, code);
            }
            if (onWritedBlock != nullptr) {
                return onWritedBlock(code);
@@ -1071,7 +1071,7 @@
                LOGI("<CLoadPort-%d>设置Cassette Type成功.", m_nIndex);
            }
            else {
                LOGI("<CLoadPort-%d>设置Cassette Type失败,code:%d", m_nIndex, code);
                LOGE("<CLoadPort-%d>设置Cassette Type失败,code:%d", m_nIndex, code);
            }
            if (onWritedBlock != nullptr) {
                return onWritedBlock(code);
@@ -1100,7 +1100,7 @@
                LOGI("<CLoadPort-%d>设置Transfer mode成功.", m_nIndex + 1);
            }
            else {
                LOGI("<CLoadPort-%d>设置Transfer mode失败,code:%d", m_nIndex + 1, code);
                LOGE("<CLoadPort-%d>设置Transfer mode失败,code:%d", m_nIndex + 1, code);
            }
            if (onWritedBlock != nullptr) {
                return onWritedBlock(code);
@@ -1129,7 +1129,7 @@
                LOGI("<CLoadPort-%d>%s Auto Change成功.", m_nIndex, bEnable ? _T("启用") : _T("禁用"));
            }
            else {
                LOGI("<CLoadPort-%d>%s  Auto Change失败,code:%d", m_nIndex, bEnable ? _T("启用") : _T("禁用"), code);
                LOGE("<CLoadPort-%d>%s  Auto Change失败,code:%d", m_nIndex, bEnable ? _T("启用") : _T("禁用"), code);
            }
            if (onWritedBlock != nullptr) {
                return onWritedBlock(code);
@@ -1209,7 +1209,7 @@
            CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass();
            pGlass->setOriginPort(m_nIndex, i);
            pGlass->addPath(m_nID, 0);
            pGlass->addPath(m_nID, 0, i + 1);
            pGlass->processEnd(m_nID, 0);
            pGlass->setID(szBuffer);
            pGlass->setType(type);
@@ -1249,7 +1249,7 @@
            CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass();
            pGlass->setOriginPort(m_nIndex, i);
            pGlass->setScheduledForProcessing(i % 2 == 1);
            pGlass->addPath(m_nID, 0);
            pGlass->addPath(m_nID, 0, i + 1);
            pGlass->processEnd(m_nID, 0);
            pGlass->setID(szBuffer);
            pGlass->setType(m_cassetteType);
@@ -1289,7 +1289,7 @@
            CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass();
            pGlass->setOriginPort(m_nIndex, nSlotIndex);
            pGlass->addPath(m_nID, 0);
            pGlass->addPath(m_nID, 0, slot.nSlotID);
            pGlass->processEnd(m_nID, 0);
            pGlass->setID(szBuffer);
            pGlass->setType(static_cast<SERVO::MaterialsType>(config.nMaterialType));
SourceCode/Bond/Servo/CMaster.cpp
@@ -131,7 +131,7 @@
            BoardVersion version{};
            int nRet = m_cclink.GetBoardVersion(version);
            if (nRet == 0) {
                LOGI("版本信息:%s.", version.toString().c_str());
                LOGD("版本信息:%s.", version.toString().c_str());
            }
            else {
                LOGE("获取CC-Link版本信息失败.");
@@ -140,7 +140,7 @@
            BoardStatus status;
            nRet = m_cclink.GetBoardStatus(status);
            if (nRet == 0) {
                LOGI("状态:%s.", status.toString().c_str());
                LOGD("状态:%s.", status.toString().c_str());
            }
            else {
                LOGE("获取CC-Link状态失败.");
@@ -422,7 +422,7 @@
                        TRACE("a0001\n", writeCode, retCode);
                    });
                if (nRet != 0) {
                    LOGI("<Master>EFEM切换Start状态失败");
                    LOGE("<Master>EFEM切换Start状态失败");
                    m_strLastError = "EFEM切换Start状态失败.";
                    goto WAIT;
                }
@@ -435,7 +435,7 @@
                        TRACE("a0002\n");
                    });
                if (nRet != 0) {
                    LOGI("<Master>Bonder1切换Start状态失败");
                    LOGE("<Master>Bonder1切换Start状态失败");
                    m_strLastError = "Bonder1切换Start状态失败.";
                    goto WAIT;
                }
@@ -448,7 +448,7 @@
                        TRACE("a0003\n");
                    });
                if (nRet != 0) {
                    LOGI("<Master>Bonder2切换Start状态失败");
                    LOGE("<Master>Bonder2切换Start状态失败");
                    m_strLastError = "Bonder2切换Start状态失败.";
                    goto WAIT;
                }
@@ -461,7 +461,7 @@
                        TRACE("a0004\n");
                    });
                if (nRet != 0) {
                    LOGI("<Master>BakeCooling切换Start状态失败");
                    LOGE("<Master>BakeCooling切换Start状态失败");
                    m_strLastError = "BakeCooling切换Start状态失败.";
                    goto WAIT;
                }
@@ -474,7 +474,7 @@
                        TRACE("a0005\n");
                    });
                if (nRet != 0) {
                    LOGI("<Master>VacuumBake切换Start状态失败");
                    LOGE("<Master>VacuumBake切换Start状态失败");
                    m_strLastError = "VacuumBake切换Start状态失败.";
                    goto WAIT;
                }
@@ -487,7 +487,7 @@
                        TRACE("a0006\n");
                    });
                if (nRet != 0) {
                    LOGI("<Master>Measurement切换Start状态失败");
                    LOGE("<Master>Measurement切换Start状态失败");
                    m_strLastError = "Measurement切换Start状态失败.";
                    goto WAIT;
                }
@@ -501,7 +501,7 @@
                for (int i = 0; i < 6; i++) {
                    if (!bIomcOk[i]) {
                        bIomcOk[6] = FALSE;
                        LOGI("<Master>%s切换Start状态失败", pEq[i]->getName().c_str());
                        LOGE("<Master>%s切换Start状态失败", pEq[i]->getName().c_str());
                    }
                }
                
@@ -545,7 +545,7 @@
                            TRACE("s000%d: ret=%d\n", i + 1, retCode);
                        });
                    if (nRet != 0) {
                        LOGI("<Master>%s切换Stop状态发送失败", pEq[i]->getName().c_str());
                        LOGE("<Master>%s切换Stop状态发送失败", pEq[i]->getName().c_str());
                        m_strLastError = pEq[i]->getName() + "切换Stop状态发送失败.";
                        bIomcOk[i] = FALSE;
                        promises[i].set_value(); // 避免 wait 阻塞
@@ -560,7 +560,7 @@
                for (int i = 0; i < 6; ++i) {
                    if (!bIomcOk[i]) {
                        bIomcOk[6] = FALSE;
                        LOGI("<Master>%s切换Stop状态失败", pEq[i]->getName().c_str());
                        LOGE("<Master>%s切换Stop状态失败", pEq[i]->getName().c_str());
                    }
                }
@@ -734,7 +734,7 @@
                if (!rmd.armState[0]) {
                    // m_nTestFlag = 1;
                    if (m_nTestFlag == 1) LOGI("createTransferTask 004df %d, %d", MaterialsType::G1, secondaryType);
                    if (m_nTestFlag == 1) LOGD("createTransferTask 004df %d, %d", MaterialsType::G1, secondaryType);
                    m_pActiveRobotTask = createTransferTask(pAligner, pVacuumBake, MaterialsType::G1, secondaryType);
                    CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
                    m_nTestFlag = 0;
@@ -798,7 +798,7 @@
                CJState state = m_pControlJob->state();
                if (state == CJState::Completed || state == CJState::Aborted || state == CJState::Failed) {
                    // ConrolJpb已完成
                    LOGI("<Master>ControlJob已经完成或失败中断");
                    LOGE("<Master>ControlJob已经完成或失败中断");
                    unlock();
                    continue;
                }
@@ -835,7 +835,7 @@
                    }
                }
                if (m_inProcesJobs.empty()) {
                    LOGI("<Master>选择当前ProcessJob失败!");
                    LOGE("<Master>选择当前ProcessJob失败!");
                    unlock();
                    continue;
                }
@@ -887,7 +887,7 @@
                // Measurement -> LoadPort
                if (rmd.armState[0] || rmd.armState[1]) {
                    LOGI("Arm1 %s, Arm2 %s.", rmd.armState[0] ? _T("不可用") : _T("可用"),
                    LOGD("Arm1 %s, Arm2 %s.", rmd.armState[0] ? _T("不可用") : _T("可用"),
                        rmd.armState[1] ? _T("不可用") : _T("可用"));
                }
                for (int s = 0; s < 4; s++) {
@@ -1312,22 +1312,22 @@
            BOOL bOk = FALSE;
            lock();
            if (m_pActiveRobotTask != nullptr) {
                LOGI("<CMaster>onPreFethedOutJob 0001.");
                LOGD("<CMaster>onPreFethedOutJob 0001.");
                if (m_pActiveRobotTask->getSrcPosition() == p->getID()) {
                    LOGI("<CMaster>onPreFethedOutJob 0002.");
                    LOGD("<CMaster>onPreFethedOutJob 0002.");
                    CGlass* pGlass = p->getGlassFromSlot(m_pActiveRobotTask->getSrcSlot());
                    if (pGlass != nullptr) {
                        LOGI("<CMaster>onPreFethedOutJob 0003.");
                        LOGD("<CMaster>onPreFethedOutJob 0003.");
                        CJobDataS* pJobDataS = pGlass->getJobDataS();
                        if (pJobDataS != nullptr
                            && pJobDataS->getCassetteSequenceNo() == pJobDataB->getCassetteSequenceNo()
                            && pJobDataS->getJobSequenceNo() == pJobDataB->getJobSequenceNo()) {
                            bOk = TRUE;
                            LOGI("<CMaster>onPreFethedOutJob, 已校验数据一致性.");
                            LOGD("<CMaster>onPreFethedOutJob, 已校验数据一致性.");
                        }
                        LOGI("<CMaster>onPreFethedOutJob 0004.");
                        LOGD("<CMaster>onPreFethedOutJob 0004.");
                        if (pJobDataS != nullptr) {
                            LOGI("<CMaster>onPreFethedOutJob 0005. %d,%d,%d,%d",
                            LOGD("<CMaster>onPreFethedOutJob 0005. %d,%d,%d,%d",
                                pJobDataS->getCassetteSequenceNo(),
                                pJobDataB->getCassetteSequenceNo(),
                                pJobDataS->getJobSequenceNo(),
@@ -1570,7 +1570,7 @@
                }
                strOut.append(szBuffer);
            }
            LOGI("<CMaster-%s>SVDataReport:%s", ((CEquipment*)pEquipment)->getName().c_str(), strOut.c_str());
            LOGD("<CMaster-%s>SVDataReport:%s", ((CEquipment*)pEquipment)->getName().c_str(), strOut.c_str());
        };
        pEquipment->setListener(listener);
        pEquipment->setCcLink(&m_cclink);
@@ -2038,12 +2038,12 @@
        pSrcEq->m_nTestFlag = m_nTestFlag;
        pTarSlot = pTarEq->getAvailableSlotForGlass(primaryType);
        pSrcSlot = pSrcEq->getProcessedSlot(primaryType, bJobMode);
        if (m_nTestFlag == 1) LOGI("createTransferTask 003 %x, %x", pTarSlot, pSrcSlot);
        if (m_nTestFlag == 1) LOGD("createTransferTask 003 %x, %x", pTarSlot, pSrcSlot);
        if (pSrcSlot == nullptr || nullptr == pTarSlot && secondaryType != SERVO::MaterialsType::G0) {
            pTarSlot = pTarEq->getAvailableSlotForGlass(secondaryType);
            pSrcSlot = pSrcEq->getProcessedSlot(secondaryType, bJobMode);
        }
        if (m_nTestFlag == 1) LOGI("createTransferTask 004 %x, %x", pTarSlot, pSrcSlot);
        if (m_nTestFlag == 1) LOGD("createTransferTask 004 %x, %x", pTarSlot, pSrcSlot);
        if (pSrcSlot != nullptr && nullptr != pTarSlot) {
            pTask = new CRobotTask();
@@ -2698,4 +2698,17 @@
        return nullptr;
    }
    int CMaster::getWipGlasses(std::vector<CGlass*>& glasses)
    {
        for (auto eq : m_listEquipment) {
            auto p = dynamic_cast<CLoadPort*>(eq);
            if (p == nullptr) {
                eq->getAllGlass(glasses);
            }
        }
        return (int)glasses.size();
    }
}
SourceCode/Bond/Servo/CMaster.h
@@ -124,6 +124,7 @@
        CLoadPort* getPortWithCarrierId(const std::string& carrierId) const;
        bool saveState() const;
        bool loadState(const std::string& path);
        int getWipGlasses(std::vector<CGlass*>& glasses);
    private:
        inline void lock() { EnterCriticalSection(&m_criticalSection); }
SourceCode/Bond/Servo/CPageCassetteCtrlCmd.cpp
@@ -119,7 +119,7 @@
                LOGI("sendCassetteCtrlCmd 成功.");
            }
            else {
                LOGI("sendCassetteCtrlCmd 失败.");
                LOGE("sendCassetteCtrlCmd 失败.");
            }
            return 0;
SourceCode/Bond/Servo/CPageGlassList.cpp
@@ -8,6 +8,7 @@
#include "GlassJson.h"
#include "CServoUtilsTool.h"
#include "ToolUnits.h"
#include <optional>
#define PAGE_SIZE                        10
@@ -207,10 +208,14 @@
void CPageGlassList::UpdatePageData()
{
    // 如果为第1页, 取出缓存Glass, 符合条件则显示;
    m_listCtrl.DeleteAllItems();
    UpdateWipData();
    // 查询
    auto& db = GlassLogDb::Instance();
    auto page = db.queryPaged(m_filters, PAGE_SIZE, PAGE_SIZE * (m_nCurPage - 1));
    m_listCtrl.DeleteAllItems();
    for (const auto& r : page.items) {
        int index = m_listCtrl.InsertItem(m_listCtrl.GetItemCount(), std::to_string(r.id).c_str());
        m_listCtrl.SetItemText(index, 1, std::to_string(r.cassetteSeqNo).c_str());
@@ -224,6 +229,7 @@
        m_listCtrl.SetItemText(index, 9, SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str());
        m_listCtrl.SetItemText(index, 10, r.path.c_str());
        m_listCtrl.SetItemText(index, 11, r.params.c_str());
        m_listCtrl.SetItemColor(index, RGB(0, 0, 0), RGB(255, 255, 0));
        // 测试反序列化
        /*
@@ -237,6 +243,42 @@
    // 上一页 / 下一页
    UpdatePageControls();
}
void CPageGlassList::UpdateWipData()
{
    if (m_nCurPage != 1) return;
    // 取出缓存Glass, 符合条件则显示;
    // 但要删除旧的数据
    std::vector<SERVO::CGlass*> wipGlasses;
    theApp.m_model.m_master.getWipGlasses(wipGlasses);
    std::vector<SERVO::CGlass*> tempGlasses = wipGlasses;
    int count = m_listCtrl.GetItemCount();
    if (count > 0) {
        for (int i = count - 1; i >= 0; i--) {
            SERVO::CGlass* pGlass = (SERVO::CGlass*)m_listCtrl.GetItemData(i);
            if (eraseGlassInVector(pGlass, wipGlasses)
                && GlassMatchesFilters(*pGlass, m_filters)) {
                // 更新
                UpdateWipRow(i, pGlass);
            }
            else {
                // 删除
                m_listCtrl.DeleteItem(i);
            }
        }
    }
    // 剩下的如符号插入
    for (auto* item : wipGlasses) {
        if (GlassMatchesFilters(*item, m_filters)) {
            InsertWipRow(item);
        }
    }
    for (auto* item : tempGlasses) {
        item->release();
    }
}
void CPageGlassList::UpdatePageControls()
@@ -256,6 +298,7 @@
    // TODO:  在此添加额外的初始化
    SetTimer(1, 3000, nullptr);
    SetTimer(2, 2000, nullptr);
    // 下拉框控件
    InitStatusCombo();
@@ -354,6 +397,11 @@
        KillTimer(1);
        InitRxWindow();
    }
    else if (nIDEvent == 2) {
        UpdateWipData();
    }
    CDialogEx::OnTimer(nIDEvent);
}
@@ -464,4 +512,72 @@
        m_nCurPage++;
        UpdatePageData();
    }
}
// 核心:WIP 的 CGlass 是否命中当前 Filters
// useEndTime=true 时用 tEnd 判时间(比如“完成列表”用 t_end),默认按 tStart。
bool CPageGlassList::GlassMatchesFilters(const SERVO::CGlass& g,
    const GlassLogDb::Filters& f,
    bool useEndTime/* = false*/)
{
    // 1) 精确字段
    if (f.classId && g.getID() != *f.classId)      return false;
    if (f.cassetteSeqNo && g.getCassetteSequenceNo() != *f.cassetteSeqNo)return false;
    if (f.jobSeqNo && g.getJobSequenceNo() != *f.jobSeqNo)     return false;
    // 2) 关键字(与 DB 保持一致:class_id / buddy_id / path / params / pretty)
    if (f.keyword) {
        const std::string& kw = *f.keyword;
        if (!(CToolUnits::containsCI(g.getID(), kw)
            || CToolUnits::containsCI(g.getBuddyId(), kw)
            || CToolUnits::containsCI(g.getPathDescription(), kw)
            || CToolUnits::containsCI(g.getParamsDescription(), kw)))
            return false;
    }
    // 3) 时间(与 DB 保持一致:默认按 t_start 过滤;需要可切到 t_end)
    if (f.tStartFrom || f.tStartTo) {
        std::optional<std::chrono::system_clock::time_point> tp = useEndTime ? g.tEnd() : g.tStart();
        // 约定:若没有对应时间戳,则视为不命中(与 DB 相同:NULL 不会命中范围)
        if (!tp) return false;
        if (f.tStartFrom && *tp < *f.tStartFrom) return false;
        if (f.tStartTo && *tp > *f.tStartTo)   return false;
    }
    return true;
}
void CPageGlassList::InsertWipRow(SERVO::CGlass* pGlass)
{
    int index = m_listCtrl.InsertItem(0, "");
    UpdateWipRow(index, pGlass);
}
void CPageGlassList::UpdateWipRow(unsigned int index, SERVO::CGlass* pGlass)
{
    ASSERT(index < m_listCtrl.GetItemCount());
    m_listCtrl.SetItemData(index, (DWORD_PTR)pGlass);
    m_listCtrl.SetItemColor(index, RGB(0, 0, 0), RGB(255, 255, 255));
    m_listCtrl.SetItemText(index, 1, std::to_string(pGlass->getCassetteSequenceNo()).c_str());
    m_listCtrl.SetItemText(index, 2, std::to_string(pGlass->getJobSequenceNo()).c_str());
    m_listCtrl.SetItemText(index, 3, pGlass->getID().c_str());
    m_listCtrl.SetItemText(index, 4, SERVO::CServoUtilsTool::getMaterialsTypeText(pGlass->getType()).c_str());
    m_listCtrl.SetItemText(index, 5, SERVO::CServoUtilsTool::getGlassStateText(pGlass->state()).c_str());
    m_listCtrl.SetItemText(index, 6, CToolUnits::TimePointToLocalString(pGlass->tStart()).c_str());
    m_listCtrl.SetItemText(index, 7, CToolUnits::TimePointToLocalString(pGlass->tEnd()).c_str());
    m_listCtrl.SetItemText(index, 8, pGlass->getBuddyId().c_str());
    m_listCtrl.SetItemText(index, 9, SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)pGlass->getAOIInspResult()).c_str());
    m_listCtrl.SetItemText(index, 10, pGlass->getPathDescription().c_str());
    m_listCtrl.SetItemText(index, 11, pGlass->getParamsDescription().c_str());
}
bool CPageGlassList::eraseGlassInVector(SERVO::CGlass* pGlass, std::vector<SERVO::CGlass*>& glasses)
{
    auto iter = std::find(glasses.begin(), glasses.end(), pGlass);
    if (iter != glasses.end()) {
        glasses.erase(iter);
        return true;
    }
    return false;
}
SourceCode/Bond/Servo/CPageGlassList.h
@@ -44,7 +44,13 @@
    void LoadData();
    void UpdatePageData();
    void UpdatePageControls();
    void InsertWipRow(SERVO::CGlass* pGlass);
    static bool GlassMatchesFilters(const SERVO::CGlass& g,
        const GlassLogDb::Filters& f,
        bool useEndTime = false);
    void UpdateWipData();
    bool eraseGlassInVector(SERVO::CGlass* pGlass, std::vector<SERVO::CGlass*>& glasses);
    void UpdateWipRow(unsigned int index, SERVO::CGlass* pGlass);
// 对话框数据
#ifdef AFX_DESIGN_TIME
SourceCode/Bond/Servo/CPath.cpp
@@ -16,10 +16,11 @@
        m_pNext = nullptr;
    }
    CPath::CPath(unsigned int nEqId, unsigned int nUnit)
    CPath::CPath(unsigned int nEqId, unsigned int nUnit, unsigned int nSlot)
    {
        m_nEqID = nEqId;
        m_nUnit = nUnit;
        m_nSlot = nSlot;
        m_timeOut = 0;
        m_timeIn = CToolUnits::getTimestamp();
        m_bProcessed = FALSE;
@@ -49,7 +50,7 @@
    void CPath::getSimpleDescription(std::string& strOut)
    {
        strOut = CServoUtilsTool::getEqUnitName(m_nEqID, m_nUnit);
        strOut = CServoUtilsTool::getEqUnitName(m_nEqID, m_nUnit, m_nSlot);
    }
    void CPath::serialize(CArchive& ar)
@@ -57,6 +58,7 @@
        if (ar.IsStoring()) {
            ar << m_nEqID;
            ar << m_nUnit;
            ar << m_nSlot;
            ar << m_timeIn;
            ar << m_timeOut;
            ar << m_bProcessed;
@@ -71,6 +73,7 @@
            ar >> m_nEqID;
            ar >> m_nUnit;
            ar >> m_nSlot;
            ar >> m_timeIn;
            ar >> m_timeOut;
            ar >> m_bProcessed;
@@ -96,6 +99,11 @@
        return m_nUnit;
    }
    unsigned int CPath::getSlot()
    {
        return m_nSlot;
    }
    void CPath::setInTime(ULONGLONG time)
    {
        m_timeIn = time;
SourceCode/Bond/Servo/CPath.h
@@ -7,7 +7,7 @@
    {
    public:
        CPath();
        CPath(unsigned int nEqId, unsigned int nUnit);
        CPath(unsigned int nEqId, unsigned int nUnit, unsigned int nSlot);
        virtual ~CPath();
    public:
@@ -21,6 +21,7 @@
        CPath* getHeadPath();
        unsigned int getEqID();
        unsigned int getUnit();
        unsigned int getSlot();
        void setInTime(ULONGLONG time);
        ULONGLONG getInTime();
        void setOutTime(ULONGLONG time);
@@ -33,6 +34,7 @@
    private:    
        unsigned int m_nEqID;
        unsigned int m_nUnit;
        unsigned int m_nSlot;
        ULONGLONG m_timeIn;
        ULONGLONG m_timeOut;
        BOOL m_bProcessed;
SourceCode/Bond/Servo/CRobotTask.cpp
@@ -220,7 +220,7 @@
                    LOGI(_T("RobotTask已下发到EFEM"));
                }
                else {
                    LOGI(_T("RobotTask下发失败"));
                    LOGE(_T("RobotTask下发失败"));
                }
                return 0;
@@ -238,7 +238,7 @@
                    LOGI(_T("RobotTask/get已下发到EFEM"));
                }
                else {
                    LOGI(_T("RobotTask/get已下发失败"));
                    LOGE(_T("RobotTask/get已下发失败"));
                }
                return 0;
@@ -261,7 +261,7 @@
                    LOGI(_T("RobotTask/put已下发到EFEM"));
                }
                else {
                    LOGI(_T("RobotTask/put已下发失败"));
                    LOGE(_T("RobotTask/put已下发失败"));
                }
                return 0;
@@ -279,7 +279,7 @@
                    LOGI(_T("RobotTask/restore-put已下发到EFEM"));
                }
                else {
                    LOGI(_T("RobotTask/restore-put已下发失败"));
                    LOGE(_T("RobotTask/restore-put已下发失败"));
                }
                return 0;
SourceCode/Bond/Servo/CServoUtilsTool.cpp
@@ -64,6 +64,80 @@
            return "AOI";
        }
        if (eqid == EQ_ID_ARM_TRAY1) {
            return "ARM1";
        }
        if (eqid == EQ_ID_ARM_TRAY2) {
            return "ARM2";
        }
        return "";
    }
    std::string CServoUtilsTool::getEqUnitName(int eqid, int unit, int slot)
    {
        char szBuffer[256];
        if (eqid == EQ_ID_LOADPORT1
            || eqid == EQ_ID_LOADPORT2
            || eqid == EQ_ID_LOADPORT3
            || eqid == EQ_ID_LOADPORT4
            ) {
            sprintf_s(szBuffer, 256, "Port%d(Slot%d)", eqid - EQ_ID_LOADPORT1 + 1, slot);
            return std::string(szBuffer);
        }
        if (eqid == EQ_ID_ALIGNER) {
            return "Aligner";
        }
        if (eqid == EQ_ID_FLIPER) {
            return "Fliper";
        }
        if (eqid == EQ_ID_VACUUMBAKE) {
            if (unit == 0) {
                sprintf_s(szBuffer, 256, "烘烤A腔(Slot%d)", slot);
                return std::string(szBuffer);
            }
            if (unit == 1) {
                sprintf_s(szBuffer, 256, "烘烤B腔(Slot%d)", slot);
                return std::string(szBuffer);
            }
        }
        if (eqid == EQ_ID_Bonder1) {
            sprintf_s(szBuffer, 256, "Bonder1(Slot%d)", slot);
            return std::string(szBuffer);
        }
        if (eqid == EQ_ID_Bonder2) {
            sprintf_s(szBuffer, 256, "Bonder2(Slot%d)", slot);
            return std::string(szBuffer);
        }
        if (eqid == EQ_ID_BAKE_COOLING) {
            if (slot == 0) return "后烘烤A腔";
            if (slot == 1) return "冷却A";
            if (slot == 0) return "后烘烤B腔";
            if (slot == 1) return "冷却B";
        }
        if (eqid == EQ_ID_MEASUREMENT) {
            return "AOI";
        }
        if (eqid == EQ_ID_ARM_TRAY1) {
            return "ARM1";
        }
        if (eqid == EQ_ID_ARM_TRAY2) {
            return "ARM2";
        }
        return "";
    }
SourceCode/Bond/Servo/CServoUtilsTool.h
@@ -12,6 +12,7 @@
    public:
        static std::string getEqUnitName(int eqid, int unit);
        static std::string getEqUnitName(int eqid, int unit, int slot);
        static std::string getMaterialsTypeText(MaterialsType type);
        static std::string getGlassStateText(SERVO::GlsState state);
        static std::string getInspResultText(SERVO::InspResult result);
SourceCode/Bond/Servo/DevicePropertyDlg.cpp
@@ -41,7 +41,7 @@
    // TODO:  在此添加额外的初始化
    SERVO::CEquipment* pEquipment = theApp.m_model.m_master.getEquipment(m_nDeviceID);
    if (nullptr == pEquipment) {
        LOGI("<设备ID:%d>获取设备属性失败。", m_nDeviceID);
        LOGE("<设备ID:%d>获取设备属性失败。", m_nDeviceID);
        return FALSE;
    }
SourceCode/Bond/Servo/GlassJson.cpp
@@ -178,6 +178,7 @@
                Json::Value n(Json::objectValue);
                n["eq_id"] = p->getEqID();
                n["unit"] = p->getUnit();
                n["slot"] = p->getUnit();
                put_ull_as_str(n, "time_in", static_cast<unsigned long long>(p->getInTime()));
                put_ull_as_str(n, "time_out", static_cast<unsigned long long>(p->getOutTime()));
                n["processed"] = p->isProcessEnd() ? true : false;
@@ -293,7 +294,8 @@
        for (const auto& n : root["path"]) {
            unsigned eq = JUInt(n, "eq_id", 0);
            unsigned unit = JUInt(n, "unit", 0);
            g.addPath(eq, unit);
            unsigned slot = JUInt(n, "slot", 0);
            g.addPath(eq, unit, slot);
            CPath* tail = nullptr;
            if (auto head = g.getPath()) tail = head->getTailPath();
SourceCode/Bond/Servo/ListCtrlEx.cpp
@@ -34,11 +34,12 @@
    {
        // 根据在 SetItemColor(DWORD iItem, COLORREF color) 设置的   
        // ITEM号和COLORREF 在摸板中查找,然后进行颜色赋值。
        //LISTITEMEX_9& itemex = m_listItemColor.GetAt(m_listItemColor.FindIndex(nmcd.dwItemSpec));
        //lplvdr->clrText = itemex.colText;
        //lplvdr->clrTextBk = itemex.colTextBk;
        //*pResult = CDRF_DODEFAULT;
        LISTITEMEX_9& itemex = m_listItemColor.GetAt(m_listItemColor.FindIndex(nmcd.dwItemSpec));
        lplvdr->clrText = itemex.colText;
        lplvdr->clrTextBk = itemex.colTextBk;
        *pResult = CDRF_DODEFAULT;
        /*
        if (nmcd.dwItemSpec % 2 == 0) {
            lplvdr->clrText = RGB(0, 0, 0);
            lplvdr->clrTextBk = RGB(235, 235, 235);
@@ -49,7 +50,7 @@
            lplvdr->clrTextBk = RGB(255, 255, 255);
            *pResult = CDRF_DODEFAULT;
        }
        */
        break;
    }
SourceCode/Bond/Servo/Model.cpp
@@ -428,13 +428,15 @@
        m_hsmsPassive.setVariableValue("PJEndID", ((SERVO::CProcessJob*)pj)->id().c_str());
        m_hsmsPassive.requestEventReportSend_PJ_End();
    };
    masterListener.onPanelStart = [&](void* pMaster, void* pj) {
        m_hsmsPassive.setVariableValue("PanelStartID", ((SERVO::CGlass*)pj)->getID().c_str());
    masterListener.onPanelStart = [&](void* pMaster, void* pPanel) {
        m_hsmsPassive.setVariableValue("PanelStartID", ((SERVO::CGlass*)pPanel)->getID().c_str());
        m_hsmsPassive.requestEventReportSend_Panel_Start();
    };
    masterListener.onPanelEnd = [&](void* pMaster, void* pj) {
        m_hsmsPassive.setVariableValue("PanelEndID", ((SERVO::CGlass*)pj)->getID().c_str());
    masterListener.onPanelEnd = [&](void* pMaster, void* pPanel) {
        m_hsmsPassive.setVariableValue("PanelEndID", ((SERVO::CGlass*)pPanel)->getID().c_str());
        m_hsmsPassive.requestEventReportSend_Panel_End();
        auto& db = GlassLogDb::Instance();
        db.insertFromCGlass((*(SERVO::CGlass*)pPanel));
    };
    m_master.setListener(masterListener);
    m_master.setContinuousTransferCount(m_configuration.getContinuousTransferCount());
SourceCode/Bond/Servo/ToolUnits.cpp
@@ -3,6 +3,7 @@
#include <chrono>
#include <memory>
#include <sstream>
#include <algorithm>
CToolUnits::CToolUnits()
@@ -491,3 +492,68 @@
    auto toUtc = LocalSTtoUtcTP(stToLocal);
    return { fromUtc, toUtc };
}
// 小工具:ASCII 不区分大小写包含(中文等非 ASCII 不受影响,但也不需要大小写转换)
bool CToolUnits::containsCI(const std::string& hay, const std::string& needle) {
    if (needle.empty()) return true;
    auto toLower = [](std::string s) { std::transform(s.begin(), s.end(), s.begin(),
        [](unsigned char c) { return (char)std::tolower(c); }); return s; };
    std::string h = toLower(hay), n = toLower(needle);
    return h.find(n) != std::string::npos;
}
// ------- 本地时间 -------
std::string CToolUnits::TimePointToLocalString(const std::optional<TP>& tp,
    const char* fmt/* = "%Y-%m-%d %H:%M:%S"*/)
{
    if (!tp) return {};
    std::time_t t = std::chrono::system_clock::to_time_t(*tp);
    std::tm tm{};
#if defined(_WIN32)
    localtime_s(&tm, &t);
#else
    localtime_r(&t, &tm);
#endif
    char buf[64]{};
    std::strftime(buf, sizeof(buf), fmt, &tm);
    return buf;
}
// ------- UTC 时间 -------
std::string CToolUnits::TimePointToUtcString(const std::optional<TP>& tp,
    const char* fmt/* = "%Y-%m-%d %H:%M:%S"*/)
{
    if (!tp) return {};
    std::time_t t = std::chrono::system_clock::to_time_t(*tp);
    std::tm tm{};
#if defined(_WIN32)
    gmtime_s(&tm, &t);
#else
    gmtime_r(&t, &tm);
#endif
    char buf[64]{};
    std::strftime(buf, sizeof(buf), fmt, &tm);
    return buf;
}
std::string CToolUnits::TimePointToLocalStringMs(const std::optional<TP>& tp)
{
    if (!tp) return {};
    using namespace std::chrono;
    auto ms_since_epoch = duration_cast<milliseconds>(tp->time_since_epoch());
    auto ms = static_cast<int>(ms_since_epoch.count() % 1000);
    std::time_t t = system_clock::to_time_t(*tp);
    std::tm tm{};
#if defined(_WIN32)
    localtime_s(&tm, &t);
#else
    localtime_r(&t, &tm);
#endif
    char date[32]{};
    std::strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &tm);
    char out[40]{};
    std::snprintf(out, sizeof(out), "%s.%03d", date, ms);
    return out;
}
SourceCode/Bond/Servo/ToolUnits.h
@@ -5,7 +5,7 @@
#include <utility>
enum class QuickRange { Today, Last7Days, ThisMonth, ThisYear };
using TP = std::chrono::system_clock::time_point;
class CToolUnits
{
public:
@@ -49,10 +49,15 @@
    static bool IsLeap(int y);
    static int DaysInMonth(int y, int m);
    static void GetTodayYMD_Local(int& y, int& m, int& d);
    static void CToolUnits::LocalCalendarMinusDays(int& y, int& m, int& d, int nDays);
    static void LocalCalendarMinusDays(int& y, int& m, int& d, int nDays);
    static std::pair<std::chrono::system_clock::time_point,
        std::chrono::system_clock::time_point>
        CToolUnits::CalcQuickRangeUtc(QuickRange r);
        CalcQuickRangeUtc(QuickRange r);
    static bool containsCI(const std::string& hay, const std::string& needle);
    static std::string TimePointToLocalString(const std::optional<TP>& tp,
        const char* fmt = "%Y-%m-%d %H:%M:%S");
    static std::string TimePointToUtcString(const std::optional<TP>& tp,
        const char* fmt = "%Y-%m-%d %H:%M:%S");
    static std::string TimePointToLocalStringMs(const std::optional<TP>& tp);
};
SourceCode/Bond/Servo/resource.h
Binary files differ