LAPTOP-SNT8I5JK\Boounion
2025-06-17 3c387cc7bcd469938fbfac8bc5435bb1e846c70f
Merge branch 'liuyang' into clh

# Conflicts:
# SourceCode/Bond/Servo/CMaster.cpp
已修改17个文件
1368 ■■■■ 文件已修改
SourceCode/Bond/Servo/CBakeCooling.cpp 295 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CBakeCooling.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CBonder.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEFEM.cpp 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.cpp 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CLoadPort.cpp 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMeasurement.cpp 295 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMeasurement.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGraph1.cpp 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CRobotCmdTestDlg.cpp 198 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CRobotCmdTestDlg.h 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CVacuumBake.cpp 295 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CVacuumBake.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/TransferManager.cpp 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/TransferManager.h 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CBakeCooling.cpp
@@ -38,6 +38,301 @@
        addPin(SERVO::PinType::OUTPUT, _T("Out"));
    }
    void CBakeCooling::initSteps()
    {
        CEquipment::initSteps();
        {
            // eq mode
            CEqModeStep* pStep = new CEqModeStep();
            pStep->setName(STEP_MODE);
            pStep->setWriteSignalDev(0x940);
            pStep->setModeDev(0x11d7d);
            if (addStep(STEP_ID_EQMODE_CHANGED, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // eq status
            CEqStatusStep* pStep = new CEqStatusStep();
            pStep->setName(STEP_STATUS);
            pStep->setWriteSignalDev(0x941);
            pStep->setStatusDev(0x11d59);
            if (addStep(STEP_ID_EQSTATUS_CHANGED, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // Eq Alarm
            static char* pszName[] = { STEP_ALARM_BLOCK1, STEP_ALARM_BLOCK2, STEP_ALARM_BLOCK3, STEP_ALARM_BLOCK4, STEP_ALARM_BLOCK5 };
            static int dev[5] = { 0x11f0e , 0x11f3b, 0x11f68, 0x11f95, 0x11fc2 };
            static int writeSignalDev[5] = { 0x942, 0x943, 0x944, 0x945, 0x946 };
            static int addr[] = { STEP_ID_EQALARM1, STEP_ID_EQALARM2, STEP_ID_EQALARM3, STEP_ID_EQALARM4, STEP_ID_EQALARM5 };
            for (int i = 0; i < 5; i++) {
                CEqAlarmStep* pStep = new CEqAlarmStep();
                pStep->setName(pszName[i]);
                pStep->setWriteSignalDev(writeSignalDev[i]);
                pStep->setAlarmDev(dev[i]);
                if (addStep(addr[i], pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            CEqReadStep* pStep = new CEqReadStep(0x12b55, 538 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        decodeProcessDataReport((CStep*)pFrom, pszData, size);
                    }
                    return -1;
                });
            pStep->setName(STEP_PROCESS);
            pStep->setWriteSignalDev(0x947);
            if (addStep(STEP_ID_PROCESS_DATA_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // eq cim mode change
            CEqCimModeChangeStep* pStep = new CEqCimModeChangeStep();
            pStep->setName(STEP_CIM_MODE_CHANGE);
            pStep->setWriteSignalDev(0x960);
            pStep->setCimModeDev(0x1c05);
            if (addStep(STEP_ID_CIMMODE_CHANGED_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // eq cim message cmd
            CEqCimMessageCmdStep* pStep = new CEqCimMessageCmdStep();
            pStep->setName(STEP_CIM_MESSAGE_CMD);
            pStep->setWriteSignalDev(0x961);
            pStep->setCimMessageDev(0x1bf0);
            if (addStep(STEP_ID_CIM_MSG_SET_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // eq current recipe change
            CEqCurrentRecipeChangeStep* pStep = new CEqCurrentRecipeChangeStep();
            pStep->setName(STEP_EQ_RURRENT_RECIPE_CHANGE);
            pStep->setWriteSignalDev(0x948);
            pStep->setDataDev(0x12850);
            if (addStep(STEP_ID_CURRENT_RECIPE_CHANGE_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // CIM Message Confirm
            // 要将int32的值拆分为两个short, 分别为msg id和panel id
            // 65538, 2Ϊmsg id, 1Ϊpanel id
            CEqReadIntStep* pStep = new CEqReadIntStep(__INT32, 0x11d80);
            pStep->setName(STEP_EQ_CIM_MESSAGE_CONFIRM);
            pStep->setWriteSignalDev(0x949);
            if (addStep(STEP_ID_CIM_MSG_CONFIRM_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            CEqCimMessageClearStep* pStep = new CEqCimMessageClearStep();
            pStep->setName(STEP_CIM_MESSAGE_CLEAR);
            pStep->setWriteSignalDev(0x962);
            pStep->setClearCimMessageDev(0x1c03);
            if (addStep(STEP_ID_CIM_MSG_CLEAR_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            CEqDateTimeSetCmdStep* pStep = new CEqDateTimeSetCmdStep();
            pStep->setName(STEP_DATETIME_SET_CMD);
            pStep->setWriteSignalDev(0x963);
            pStep->setDateTimeDev(0x1c06);
            if (addStep(STEP_ID_DATETIME_SET_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            CEqModeChangeStep* pStep = new CEqModeChangeStep();
            pStep->setName(STEP_EQ_MODE_CHANGE);
            pStep->setWriteSignalDev(0x965);
            pStep->setEqModeDev(0x1c0e);
            if (addStep(STEP_ID_EQMODE_CHANGE_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // 请求主配方列表的step
            CEqWriteStep* pStep = new CEqWriteStep();
            pStep->setName(STEP_EQ_MASTER_RECIPE_LIST_REQ);
            pStep->setWriteSignalDev(0x966);
            pStep->setDataDev(0x24fa);
            if (addStep(STEP_ID_MASTER_RECIPE_LIST_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // master recipe list report
            CEqReadStep* pStep = new CEqReadStep(0x12955, 255 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        // 此处解释配方数据
                        short ret = decodeRecipeListReport(pszData, size);
                        pStep->setReturnCode(ret);
                    }
                    pStep->setReturnCode(MRLRC_OK);
                    return -1;
                });
            pStep->setName(STEP_EQ_MASTER_RECIPE_LIST);
            pStep->setWriteSignalDev(0x94b);
            pStep->setReturnDev(0x37ad);
            if (addStep(STEP_ID_MASTER_RECIPE_LIST_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // 请求配方参数
            //CEqWriteStep* pStep = new CEqWriteStep();
            //pStep->setName(STEP_EQ_RECIPE_PARAMETER_REQ);
            //pStep->setWriteSignalDev(0x967);
            //pStep->setDataDev(0x379b);
            //if (addStep(STEP_ID_RECIPE_PARAMETER_CMD_REPLY, pStep) != 0) {
            //    delete pStep;
            //}
        }
        {
            // recipe parameter report
            //CEqReadStep* pStep = new CEqReadStep(0x1aa54, 257 * 2,
            //    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
            //        if (code == ROK && pszData != nullptr && size > 0) {
            //            // 此处解释配方数据
            //            short ret = decodeRecipeParameterReport(pszData, size);
            //            pStep->setReturnCode(ret);
            //        }
            //        pStep->setReturnCode(MRLRC_OK);
            //        return -1;
            //    });
            //pStep->setName(STEP_EQ_RECIPE_PARAMETER);
            //pStep->setWriteSignalDev(0x94c);
            //pStep->setReturnDev(m_nIndex == 0 ? 0x126c : 0x1bbc);
            //if (addStep(STEP_ID_RECIPE_PARAMETER_REPORT, pStep) != 0) {
            //    delete pStep;
            //}
        }
        // 使用CEqReadStep替换CEqJobEventStep
        {
            // Received Job Report Upstream #1~9
            char szBuffer[256];
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x10c90 + 320 * i, 320 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeReceivedJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_RECEIVED_JOB_UPSn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x900 + i);
                if (addStep(STEP_ID_RECIVE_JOB_UPS1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Sent Out Job Report Downstream #1~9
            char szBuffer[256];
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x10000 + 320 * i, 320 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeReceivedJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_SENT_OUT_JOB_DOWNSn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x90a + i);
                if (addStep(STEP_ID_SENT_OUT_JOB_DOWNS1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Fetched Out Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x11c31 + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeFetchedOutJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_FETCHED_OUT_JOBn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x923 + i);
                if (addStep(STEP_ID_FETCHED_OUT_JOB_REPORT1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Stored Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x11b23 + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeStoredJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_STORED_JOBn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x914 + i);
                if (addStep(STEP_ID_STORE_JOB_REPORT1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
    }
    // 必须要实现的虚函数,在此初始化Slot信息
    void CBakeCooling::initSlots()
    {
SourceCode/Bond/Servo/CBakeCooling.h
@@ -15,6 +15,7 @@
        virtual void init();
        virtual void term();
        virtual void initPins();
        virtual void initSteps();
        virtual void initSlots();
        virtual void onTimer(UINT nTimerid);
        virtual void serialize(CArchive& ar);
SourceCode/Bond/Servo/CBonder.cpp
@@ -244,7 +244,7 @@
        {
            // Received Job Report Upstream #1~9
            char szBuffer[256];
            for (int i = 0; i < 9; i++) {
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep((m_nIndex == 0 ? 0x8c90 : 0xcc90) + 320 * i, 320 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
@@ -267,7 +267,7 @@
        {
            // Sent Out Job Report Downstream #1~9
            char szBuffer[256];
            for (int i = 0; i < 9; i++) {
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep((m_nIndex == 0 ? 0x8000 : 0xc000) + 320 * i, 320 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
@@ -291,7 +291,7 @@
        {
            // Fetched Out Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 15; i++) {
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep((m_nIndex == 0 ? 0x9c31 : 0xdc31) + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
@@ -315,7 +315,7 @@
        {
            // Stored Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 15; i++) {
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep((m_nIndex == 0 ? 0x9b23 : 0xdb23) + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
SourceCode/Bond/Servo/CEFEM.cpp
@@ -22,7 +22,7 @@
        m_pPort[3] = nullptr;
        m_pAligner = nullptr;
        m_pFliper = nullptr;
        m_robotData.status = ROBOT_STATUS::Idle;
        m_robotData.status = ROBOT_STATUS::Setup;
        m_robotData.position = ROBOT_POSITION::Port1;
        m_robotData.armState[0] = FALSE;
        m_robotData.armState[1] = FALSE;
@@ -366,7 +366,7 @@
            // Eq mode
            CEqModeStep* pStep = new CEqModeStep();
            pStep->setName(STEP_MODE);
            pStep->setWriteSignalDev(0x50);
            pStep->setWriteSignalDev(0x40);
            pStep->setModeDev(0x5d7d);
            if (addStep(STEP_ID_EQMODE_CHANGED, pStep) != 0) {
                delete pStep;
@@ -377,7 +377,7 @@
            // Eq Status
            CEqStatusStep* pStep = new CEqStatusStep();
            pStep->setName(STEP_STATUS);
            pStep->setWriteSignalDev(0x51);
            pStep->setWriteSignalDev(0x41);
            pStep->setStatusDev(0x5d59);
            if (addStep(STEP_ID_EQSTATUS_CHANGED, pStep) != 0) {
                delete pStep;
@@ -388,7 +388,7 @@
            // Eq Alarm
            static char* pszName[] = { STEP_ALARM_BLOCK1, STEP_ALARM_BLOCK2, STEP_ALARM_BLOCK3, STEP_ALARM_BLOCK4, STEP_ALARM_BLOCK5 };
            static int dev[] = { 0x5f0e , 0x5f3b, 0x5f68, 0x5f95, 0x5fc2 };
            static int writeSignalDev[] = { 0x52, 0x53, 0x54, 0x55, 0x56 };
            static int writeSignalDev[] = { 0x42, 0x43, 0x44, 0x45, 0x46 };
            static int addr[] = { STEP_ID_EQALARM1, STEP_ID_EQALARM2, STEP_ID_EQALARM3, STEP_ID_EQALARM4, STEP_ID_EQALARM5 };
            for (int i = 0; i < 5; i++) {
@@ -407,7 +407,7 @@
            // eq process
            CEqProcessStep* pStep = new CEqProcessStep();
            pStep->setName(STEP_PROCESS);
            pStep->setWriteSignalDev(0x57);
            pStep->setWriteSignalDev(0x47);
            pStep->setProcessDev(0x6b55);
            if (addStep(STEP_ID_PROCESS_DATA_REPORT, pStep) != 0) {
                delete pStep;
@@ -439,7 +439,7 @@
        {
            // CIM Message Confirm
            CEqReadIntStep* pStep = new CEqReadIntStep(__INT32, 0x5f80);
            CEqReadIntStep* pStep = new CEqReadIntStep(__INT32, 0x5d80);
            pStep->setName(STEP_EQ_CIM_MESSAGE_CONFIRM);
            pStep->setWriteSignalDev(0x49);
            if (addStep(STEP_ID_CIM_MSG_CONFIRM_REPORT, pStep) != 0) {
@@ -502,7 +502,7 @@
            // eq mode change
            CEqModeChangeStep* pStep = new CEqModeChangeStep();
            pStep->setName(STEP_EQ_MODE_CHANGE);
            pStep->setWriteSignalDev(0x65);
            pStep->setWriteSignalDev(0x40);
            pStep->setEqModeDev(0x1E);
            if (addStep(STEP_ID_EQMODE_CHANGE_CMD_REPLY, pStep) != 0) {
                delete pStep;
@@ -549,55 +549,7 @@
                pStep->setName(szBuffer);
                pStep->setProp("Upstream", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x0 + i);
                if (addStep(STEP_ID_FETCHED_OUT_JOB_REPORT1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Fetched Out Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 15; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x5c31 + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeFetchedOutJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_FETCHED_OUT_JOBn, i+1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x023 + i);
                if (addStep(STEP_ID_FETCHED_OUT_JOB_REPORT1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Store Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 15; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x5b23 + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeStoredJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_STORED_JOBn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0x014 + i);
                if (addStep(STEP_ID_STORE_JOB_REPORT1 + i, pStep) != 0) {
                if (addStep(STEP_ID_RECIVE_JOB_UPS1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
@@ -619,7 +571,7 @@
            CEqWriteStep* pStep = new CEqWriteStep();
            pStep->setName(STEP_EFEM_ROBOT_CMD);
            pStep->setWriteSignalDev(0x14D);
            pStep->setDataDev(0x90a);
            pStep->setDataDev(0x5c7);
            if (addStep(STEP_ID_ROBOT_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
SourceCode/Bond/Servo/CEquipment.cpp
@@ -575,6 +575,10 @@
        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);
    }
    BOOL CEquipment::isBitOn(const char* pszData, size_t size, int index)
SourceCode/Bond/Servo/CLoadPort.cpp
@@ -92,7 +92,7 @@
            // Type
            static char* pszName[] = { STEP_EQ_PORT1_TYPE, STEP_EQ_PORT2_TYPE, STEP_EQ_PORT3_TYPE, STEP_EQ_PORT4_TYPE };
            static int dev[] = { 0x6010 , 0x6020, 0x6030, 0x6040 };
            static int writeSignalDev[] = { 0xa0, 0xa1, 0xa2, 0xa3 };
            static int writeSignalDev[] = { 0x90, 0x91, 0x92, 0x93 };
            static int addr[] = { STEP_ID_PORT1_TYPE_CHANGE, STEP_ID_PORT2_TYPE_CHANGE, STEP_ID_PORT3_TYPE_CHANGE, STEP_ID_PORT4_TYPE_CHANGE };
            CEqReadStep* pStep = new CEqReadStep(dev[m_nIndex], sizeof(short),
@@ -113,7 +113,7 @@
            // Mode
            static char* pszName[] = { STEP_EQ_PORT1_MODE, STEP_EQ_PORT2_MODE, STEP_EQ_PORT3_MODE, STEP_EQ_PORT4_MODE };
            static int dev[] = { 0x6011, 0x6021, 0x6031, 0x6041 };
            static int writeSignalDev[] = { 0xa8, 0xa9, 0xaa, 0xab };
            static int writeSignalDev[] = { 0x98, 0x99, 0x9a, 0x9b };
            static int addr[] = { STEP_ID_PORT1_MODE_CHANGE, STEP_ID_PORT2_MODE_CHANGE, STEP_ID_PORT3_MODE_CHANGE, STEP_ID_PORT4_MODE_CHANGE };
            CEqReadStep* pStep = new CEqReadStep(dev[m_nIndex], sizeof(short),
@@ -134,7 +134,7 @@
            // Cassette type
            static char* pszName[] = { STEP_EQ_PORT1_CASSETTE_TYPE, STEP_EQ_PORT2_CASSETTE_TYPE, STEP_EQ_PORT3_CASSETTE_TYPE, STEP_EQ_PORT4_CASSETTE_TYPE };
            static int dev[] = { 0x6012, 0x6022, 0x6032, 0x6042 };
            static int writeSignalDev[] = { 0xb0, 0xb1, 0xb2, 0xb3 };
            static int writeSignalDev[] = { 0xa0, 0xa1, 0xa2, 0xa3 };
            static int addr[] = { STEP_ID_PORT1_CASSETTE_TYPE_CHANGE, STEP_ID_PORT2_CASSETTE_TYPE_CHANGE, STEP_ID_PORT3_CASSETTE_TYPE_CHANGE, STEP_ID_PORT4_CASSETTE_TYPE_CHANGE };
            CEqReadStep* pStep = new CEqReadStep(dev[m_nIndex], sizeof(short),
@@ -155,7 +155,7 @@
            // Transfer type
            static char* pszName[] = { STEP_EQ_PORT1_TRANSFER_MODE, STEP_EQ_PORT2_TRANSFER_MODE, STEP_EQ_PORT3_TRANSFER_MODE, STEP_EQ_PORT4_TRANSFER_MODE };
            static int dev[] = { 0x6014, 0x6024, 0x6034, 0x6044 };
            static int writeSignalDev[] = { 0xb8, 0xb9, 0xba, 0xbb };
            static int writeSignalDev[] = { 0xa8, 0xa9, 0xaa, 0xab };
            static int addr[] = { STEP_ID_PORT1_TRANSFER_MODE_CHANGE, STEP_ID_PORT2_TRANSFER_MODE_CHANGE, STEP_ID_PORT3_TRANSFER_MODE_CHANGE, STEP_ID_PORT4_TRANSFER_MODE_CHANGE };
            CEqReadStep* pStep = new CEqReadStep(dev[m_nIndex], sizeof(short),
@@ -176,7 +176,7 @@
            // Port enable
            static char* pszName[] = { STEP_EQ_PORT1_ENABLE, STEP_EQ_PORT2_ENABLE, STEP_EQ_PORT3_ENABLE, STEP_EQ_PORT4_ENABLE };
            static int dev[] = { 0x6015, 0x6025, 0x6035, 0x6045 };
            static int writeSignalDev[] = { 0xc0, 0xc1, 0xc2, 0xc3 };
            static int writeSignalDev[] = { 0xb0, 0xb1, 0xb2, 0xb3 };
            static int addr[] = { STEP_ID_PORT1_ENABLE_MODE_CHANGE, STEP_ID_PORT2_ENABLE_MODE_CHANGE, STEP_ID_PORT3_ENABLE_MODE_CHANGE, STEP_ID_PORT4_ENABLE_MODE_CHANGE };
            CEqReadStep* pStep = new CEqReadStep(dev[m_nIndex], sizeof(short),
@@ -345,6 +345,50 @@
                if (addStep(addr[i][m_nIndex], pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Fetched Out Job Report #1~15
            char szBuffer[256];
            CEqReadStep* pStep = new CEqReadStep(0x5c31 + 18 * m_nIndex, 18 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                        if (port > 0) {
                            decodeFetchedOutJobReport((CStep*)pFrom, port, pszData, size);
                        }
                    }
                    return -1;
                });
            sprintf_s(szBuffer, "%s%d", STEP_EQ_FETCHED_OUT_JOBn, m_nIndex + 1);
            pStep->setName(szBuffer);
            pStep->setProp("Port", (void*)(__int64)(m_nIndex + 1));
            pStep->setWriteSignalDev(0x023 + m_nIndex);
            if (addStep(STEP_ID_FETCHED_OUT_JOB_REPORT1 + m_nIndex, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // Store Job Report #1~15
            char szBuffer[256];
            CEqReadStep* pStep = new CEqReadStep(0x5b23 + 18 * m_nIndex, 18 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                        if (port > 0) {
                            decodeStoredJobReport((CStep*)pFrom, port, pszData, size);
                        }
                    }
                    return -1;
                });
            sprintf_s(szBuffer, "%s%d", STEP_EQ_STORED_JOBn, m_nIndex + 1);
            pStep->setName(szBuffer);
            pStep->setProp("Port", (void*)(__int64)(m_nIndex + 1));
            pStep->setWriteSignalDev(0x014 + m_nIndex);
            if (addStep(STEP_ID_STORE_JOB_REPORT1 + m_nIndex, pStep) != 0) {
                delete pStep;
            }
        }
    }
@@ -820,6 +864,8 @@
    void CLoadPort::onReceiveLBData(const char* pszData, size_t size)
    {
        __super::onReceiveLBData(pszData, size);
        static int type[] = { STEP_ID_PORT1_TYPE_CHANGE, STEP_ID_PORT2_TYPE_CHANGE,
            STEP_ID_PORT3_TYPE_CHANGE, STEP_ID_PORT4_TYPE_CHANGE };
        static int mode[] = { STEP_ID_PORT1_MODE_CHANGE, STEP_ID_PORT2_MODE_CHANGE,
SourceCode/Bond/Servo/CMaster.cpp
@@ -613,16 +613,13 @@
            // 读标志位
            for (auto item : m_listEquipment) {
                if (item->getID() == EQ_ID_Bonder1 || item->getID() == EQ_ID_Bonder2
                    || item->getID() == EQ_ID_EFEM) {
                    const StationIdentifier& station = item->getStation();
                    MemoryBlock& block = item->getReadBitBlock();
                const StationIdentifier& station = item->getStation();
                MemoryBlock& block = item->getReadBitBlock();
                    int nRet = m_cclink.ReadData2(station, (DeviceType)block.type,
                        block.start, block.size, block.buffer);
                    if (0 == nRet) {
                        item->onReceiveLBData(block.buffer, block.size);
                    }
                int nRet = m_cclink.ReadData2(station, (DeviceType)block.type,
                    block.start, block.size, block.buffer);
                if (0 == nRet) {
                    item->onReceiveLBData(block.buffer, block.size);
                }
            }
        }
@@ -854,7 +851,7 @@
        pEquipment->setBaseAlarmId(BASE_ALARM_EFEM);
        pEquipment->setName("VacuumBake(G1)");
        pEquipment->setDescription("VacuumBake(G1).");
        pEquipment->setReadBitBlock(0x4000, 0x45ff);
        pEquipment->setReadBitBlock(0x5c00, 0x66ff);
        pEquipment->setStation(0, 255);
        addToEquipmentList(pEquipment);
@@ -965,7 +962,7 @@
        pEquipment->setBaseAlarmId(BASE_ALARM_EFEM);
        pEquipment->setName("BakeCooling");
        pEquipment->setDescription("BakeCooling.");
        pEquipment->setReadBitBlock(0x4000, 0x45ff);
        pEquipment->setReadBitBlock(0x5100, 0x5bff);
        pEquipment->setStation(0, 255);
        addToEquipmentList(pEquipment);
SourceCode/Bond/Servo/CMeasurement.cpp
@@ -38,6 +38,301 @@
        addPin(SERVO::PinType::OUTPUT, _T("Out2"));
    }
    void CMeasurement::initSteps()
    {
        CEquipment::initSteps();
        {
            // eq mode
            CEqModeStep* pStep = new CEqModeStep();
            pStep->setName(STEP_MODE);
            pStep->setWriteSignalDev(0xf40);
            pStep->setModeDev(0x19d7d);
            if (addStep(STEP_ID_EQMODE_CHANGED, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // eq status
            CEqStatusStep* pStep = new CEqStatusStep();
            pStep->setName(STEP_STATUS);
            pStep->setWriteSignalDev(0xf41);
            pStep->setStatusDev(0x19d59);
            if (addStep(STEP_ID_EQSTATUS_CHANGED, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // Eq Alarm
            static char* pszName[] = { STEP_ALARM_BLOCK1, STEP_ALARM_BLOCK2, STEP_ALARM_BLOCK3, STEP_ALARM_BLOCK4, STEP_ALARM_BLOCK5 };
            static int dev[5] = { 0x19f0e , 0x19f3b, 0x19f68, 0x19f95, 0x19fc2 };
            static int writeSignalDev[5] = { 0xf42, 0xf43, 0xf44, 0xf45, 0xf46 };
            static int addr[] = { STEP_ID_EQALARM1, STEP_ID_EQALARM2, STEP_ID_EQALARM3, STEP_ID_EQALARM4, STEP_ID_EQALARM5 };
            for (int i = 0; i < 5; i++) {
                CEqAlarmStep* pStep = new CEqAlarmStep();
                pStep->setName(pszName[i]);
                pStep->setWriteSignalDev(writeSignalDev[i]);
                pStep->setAlarmDev(dev[i]);
                if (addStep(addr[i], pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            CEqReadStep* pStep = new CEqReadStep(0x1ab55, 538 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        decodeProcessDataReport((CStep*)pFrom, pszData, size);
                    }
                    return -1;
                });
            pStep->setName(STEP_PROCESS);
            pStep->setWriteSignalDev(0xf47);
            if (addStep(STEP_ID_PROCESS_DATA_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // eq cim mode change
            CEqCimModeChangeStep* pStep = new CEqCimModeChangeStep();
            pStep->setName(STEP_CIM_MODE_CHANGE);
            pStep->setWriteSignalDev(0xf60);
            pStep->setCimModeDev(0x2ea5);
            if (addStep(STEP_ID_CIMMODE_CHANGED_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // eq cim message cmd
            CEqCimMessageCmdStep* pStep = new CEqCimMessageCmdStep();
            pStep->setName(STEP_CIM_MESSAGE_CMD);
            pStep->setWriteSignalDev(0xf61);
            pStep->setCimMessageDev(0x2e90);
            if (addStep(STEP_ID_CIM_MSG_SET_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // eq current recipe change
            CEqCurrentRecipeChangeStep* pStep = new CEqCurrentRecipeChangeStep();
            pStep->setName(STEP_EQ_RURRENT_RECIPE_CHANGE);
            pStep->setWriteSignalDev(0xf48);
            pStep->setDataDev(0x1a850);
            if (addStep(STEP_ID_CURRENT_RECIPE_CHANGE_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // CIM Message Confirm
            // 要将int32的值拆分为两个short, 分别为msg id和panel id
            // 65538, 2Ϊmsg id, 1Ϊpanel id
            CEqReadIntStep* pStep = new CEqReadIntStep(__INT32, 0x19d80);
            pStep->setName(STEP_EQ_CIM_MESSAGE_CONFIRM);
            pStep->setWriteSignalDev(0xf49);
            if (addStep(STEP_ID_CIM_MSG_CONFIRM_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            CEqCimMessageClearStep* pStep = new CEqCimMessageClearStep();
            pStep->setName(STEP_CIM_MESSAGE_CLEAR);
            pStep->setWriteSignalDev(0xf62);
            pStep->setClearCimMessageDev(0x2ea3);
            if (addStep(STEP_ID_CIM_MSG_CLEAR_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            CEqDateTimeSetCmdStep* pStep = new CEqDateTimeSetCmdStep();
            pStep->setName(STEP_DATETIME_SET_CMD);
            pStep->setWriteSignalDev(0xf63);
            pStep->setDateTimeDev(0x2ea6);
            if (addStep(STEP_ID_DATETIME_SET_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            CEqModeChangeStep* pStep = new CEqModeChangeStep();
            pStep->setName(STEP_EQ_MODE_CHANGE);
            pStep->setWriteSignalDev(0xf65);
            pStep->setEqModeDev(0x2eae);
            if (addStep(STEP_ID_EQMODE_CHANGE_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // 请求主配方列表的step
            CEqWriteStep* pStep = new CEqWriteStep();
            pStep->setName(STEP_EQ_MASTER_RECIPE_LIST_REQ);
            pStep->setWriteSignalDev(0xf66);
            pStep->setDataDev(0x379a);
            if (addStep(STEP_ID_MASTER_RECIPE_LIST_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // master recipe list report
            CEqReadStep* pStep = new CEqReadStep(0x1a955, 255 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        // 此处解释配方数据
                        short ret = decodeRecipeListReport(pszData, size);
                        pStep->setReturnCode(ret);
                    }
                    pStep->setReturnCode(MRLRC_OK);
                    return -1;
                });
            pStep->setName(STEP_EQ_MASTER_RECIPE_LIST);
            pStep->setWriteSignalDev(0xf4b);
            pStep->setReturnDev(0x37ad);
            if (addStep(STEP_ID_MASTER_RECIPE_LIST_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // 请求配方参数
            //CEqWriteStep* pStep = new CEqWriteStep();
            //pStep->setName(STEP_EQ_RECIPE_PARAMETER_REQ);
            //pStep->setWriteSignalDev(0xf67);
            //pStep->setDataDev(0x379b);
            //if (addStep(STEP_ID_RECIPE_PARAMETER_CMD_REPLY, pStep) != 0) {
            //    delete pStep;
            //}
        }
        {
            // recipe parameter report
            //CEqReadStep* pStep = new CEqReadStep(0x1aa54, 257 * 2,
            //    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
            //        if (code == ROK && pszData != nullptr && size > 0) {
            //            // 此处解释配方数据
            //            short ret = decodeRecipeParameterReport(pszData, size);
            //            pStep->setReturnCode(ret);
            //        }
            //        pStep->setReturnCode(MRLRC_OK);
            //        return -1;
            //    });
            //pStep->setName(STEP_EQ_RECIPE_PARAMETER);
            //pStep->setWriteSignalDev(0xf4c);
            //pStep->setReturnDev(m_nIndex == 0 ? 0x126c : 0x1bbc);
            //if (addStep(STEP_ID_RECIPE_PARAMETER_REPORT, pStep) != 0) {
            //    delete pStep;
            //}
        }
        // 使用CEqReadStep替换CEqJobEventStep
        {
            // Received Job Report Upstream #1~9
            char szBuffer[256];
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x18c90 + 320 * i, 320 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeReceivedJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_RECEIVED_JOB_UPSn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0xf00 + i);
                if (addStep(STEP_ID_RECIVE_JOB_UPS1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Sent Out Job Report Downstream #1~9
            char szBuffer[256];
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x18000 + 320 * i, 320 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeReceivedJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_SENT_OUT_JOB_DOWNSn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0xf0a + i);
                if (addStep(STEP_ID_SENT_OUT_JOB_DOWNS1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Fetched Out Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x19c31 + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeFetchedOutJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_FETCHED_OUT_JOBn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0xf23 + i);
                if (addStep(STEP_ID_FETCHED_OUT_JOB_REPORT1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Stored Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x19b23 + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeStoredJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_STORED_JOBn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0xf14 + i);
                if (addStep(STEP_ID_STORE_JOB_REPORT1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
    }
    // 必须要实现的虚函数,在此初始化Slot信息
    void CMeasurement::initSlots()
    {
SourceCode/Bond/Servo/CMeasurement.h
@@ -15,13 +15,13 @@
        virtual void init();
        virtual void term();
        virtual void initPins();
        virtual void initSteps();
        virtual void initSlots();
        virtual void onTimer(UINT nTimerid);
        virtual void serialize(CArchive& ar);
        virtual void getAttributeVector(CAttributeVector& attrubutes);
        virtual int recvIntent(CPin* pPin, CIntent* pIntent);
        virtual int getIndexerOperationModeBaseValue();
    };
}
SourceCode/Bond/Servo/CPageGraph1.cpp
@@ -100,6 +100,18 @@
                            DeviceStatus status = bAlive ? DeviceStatus::ONLINE : DeviceStatus::OFFLINE;
                            UpdateDeviceStatus(INDICATE_BONDER2, status);
                        }
                        else if (EQ_ID_VACUUMBAKE == nID) {
                            DeviceStatus status = bAlive ? DeviceStatus::ONLINE : DeviceStatus::OFFLINE;
                            UpdateDeviceStatus(INDICATE_VACUUM_BAKE, status);
                        }
                        else if (EQ_ID_BAKE_COOLING == nID) {
                            DeviceStatus status = bAlive ? DeviceStatus::ONLINE : DeviceStatus::OFFLINE;
                            UpdateDeviceStatus(INDICATE_BAKE_COOLING, status);
                        }
                        else if (EQ_ID_MEASUREMENT == nID) {
                            DeviceStatus status = bAlive ? DeviceStatus::ONLINE : DeviceStatus::OFFLINE;
                            UpdateDeviceStatus(INDICATE_MEASUREMENT, status);
                        }
                    }
                }
            }
SourceCode/Bond/Servo/CRobotCmdTestDlg.cpp
@@ -32,6 +32,28 @@
    {_T("SendPutAndHome"),       {true,  false, false, true,  true }}
};
std::map<CString, int> g_mapDeviceSlotCount = {
    {_T("Port1"), 8},
    {_T("Port2"), 8},
    {_T("Port3"), 8},
    {_T("Port4"), 8},
    {_T("RB1"), 1},
    {_T("RB2"), 1},
    {_T("AL"), 1},
    {_T("FLIP"), 1},
    {_T("Bonder1-上产品"), 1},
    {_T("Bonder1-下产品"), 1},
    {_T("Bonder2-上产品"), 1},
    {_T("Bonder2-下产品"), 1},
    {_T("VacBakeA腔"), 1},
    {_T("VacBakeB腔"), 1},
    {_T("BakecCoolingA烘烤"), 1},
    {_T("BakecCoolingA冷却"), 1},
    {_T("BakecCoolingB烘烤"), 1},
    {_T("BakecCoolingB冷却"), 1},
    {_T("Measurement"), 1}
};
// CRobotCmdTestDlg 对话框
IMPLEMENT_DYNAMIC(CRobotCmdTestDlg, CDialogEx)
@@ -64,8 +86,10 @@
}
BEGIN_MESSAGE_MAP(CRobotCmdTestDlg, CDialogEx)
    ON_CBN_SELCHANGE(IDC_COMBO_CMD_TYPE, &CRobotCmdTestDlg::OnCbnSelchangeComboCmdType)
    ON_BN_CLICKED(IDC_BUTTON_EXECUTE, &CRobotCmdTestDlg::OnBnClickedButtonExecute)
    ON_CBN_SELCHANGE(IDC_COMBO_CMD_TYPE, &CRobotCmdTestDlg::OnSelchangeComboCmdType)
    ON_CBN_SELCHANGE(IDC_COMBO_GET_POS, &CRobotCmdTestDlg::OnSelchangeComboGetPos)
    ON_CBN_SELCHANGE(IDC_COMBO_PUT_POS, &CRobotCmdTestDlg::OnSelchangeComboPutPos)
END_MESSAGE_MAP()
// CRobotCmdTestDlg 消息处理程序
@@ -81,11 +105,6 @@
    }
    m_comboCmdType.SetCurSel(0);
    // 初始化命令输入控件
    if (!g_mapQuickCmd.empty()) {
        UpdateCommandInputUI(g_mapQuickCmd.begin()->first);
    }
    // 初始化 Arm No(1:Arm#1,2:Arm#2)
    m_comboArmNo.AddString(_T("1"));
    m_comboArmNo.AddString(_T("2"));
@@ -93,19 +112,25 @@
    // 示例设备名称列表
    CStringList eqNameList;
    eqNameList.AddTail(_T("PORT 1"));                // 1 1 UNIT
    eqNameList.AddTail(_T("PORT 2"));                // 2 1 UNIT
    eqNameList.AddTail(_T("PORT 3"));                // 3 1 UNIT
    eqNameList.AddTail(_T("PORT 4"));                // 4 1 UNIT
    eqNameList.AddTail(_T("RB1"));                    // 5 1 UNIT
    eqNameList.AddTail(_T("RB2"));                    // 6 1 UNIT
    eqNameList.AddTail(_T("ALIGN"));                // 7 1 UNIT
    eqNameList.AddTail(_T("FLIP"));                    // 8 1 UNIT
    eqNameList.AddTail(_T("VAC BAKE"));                // 9 2 UNIT
    eqNameList.AddTail(_T("BONDER1"));                // 10 2 UNIT
    eqNameList.AddTail(_T("BONDER2"));                // 11 2 UNIT
    eqNameList.AddTail(_T("POST BAKE(COOLING)"));    // 12 4 UNIT
    eqNameList.AddTail(_T("MEASUREMENT"));            // 13 1 UNIT
    eqNameList.AddTail(_T("Port1"));
    eqNameList.AddTail(_T("Port2"));
    eqNameList.AddTail(_T("Port3"));
    eqNameList.AddTail(_T("Port4"));
    eqNameList.AddTail(_T("RB1"));
    eqNameList.AddTail(_T("RB2"));
    eqNameList.AddTail(_T("AL"));
    eqNameList.AddTail(_T("FLIP"));
    eqNameList.AddTail(_T("Bonder1-上产品"));
    eqNameList.AddTail(_T("Bonder1-下产品"));
    eqNameList.AddTail(_T("Bonder2-上产品"));
    eqNameList.AddTail(_T("Bonder2-下产品"));
    eqNameList.AddTail(_T("VacBakeA腔"));
    eqNameList.AddTail(_T("VacBakeB腔"));
    eqNameList.AddTail(_T("BakecCoolingA烘烤"));
    eqNameList.AddTail(_T("BakecCoolingA冷却"));
    eqNameList.AddTail(_T("BakecCoolingB烘烤"));
    eqNameList.AddTail(_T("BakecCoolingB冷却"));
    eqNameList.AddTail(_T("Measurement"));
    for (POSITION pos = eqNameList.GetHeadPosition(); pos != NULL;) {
        CString item = eqNameList.GetNext(pos);
@@ -115,15 +140,16 @@
    m_comboGetPos.SetCurSel(0);
    m_comboPutPos.SetCurSel(0);
    // 初始化 Slot(默认从 1 到 25)
    for (int i = 1; i < 26; ++i) {
        CString str;
        str.Format(_T("%d"), i);
        m_comboGetSlot.AddString(str);
        m_comboPutSlot.AddString(str);
    // 初始化 Slot
    m_comboGetPos.SetCurSel(0);
    m_comboPutPos.SetCurSel(0);
    UpdateSlotList(&m_comboGetPos, &m_comboGetSlot);
    UpdateSlotList(&m_comboPutPos, &m_comboPutSlot);
    // 初始化命令输入控件
    if (!g_mapQuickCmd.empty()) {
        UpdateCommandInputUI(g_mapQuickCmd.begin()->first);
    }
    m_comboGetSlot.SetCurSel(0);
    m_comboPutSlot.SetCurSel(0);
    // 快捷命令执行映射表
    m_mapCmdExec = {
@@ -204,11 +230,16 @@
    }
    const QuickCmdFieldMask& mask = it->second;
    GetDlgItem(IDC_COMBO_ARM_NO)->EnableWindow(mask.useArm);
    GetDlgItem(IDC_COMBO_GET_POS)->EnableWindow(mask.useGetPos);
    GetDlgItem(IDC_COMBO_GET_SLOT)->EnableWindow(mask.useGetSlot);
    GetDlgItem(IDC_COMBO_PUT_POS)->EnableWindow(mask.usePutPos);
    GetDlgItem(IDC_COMBO_PUT_SLOT)->EnableWindow(mask.usePutSlot);
    m_comboArmNo.SetCurSel(0);
    m_comboArmNo.EnableWindow(mask.useArm);
    m_comboGetPos.SetCurSel(0);
    m_comboGetPos.EnableWindow(mask.useGetPos);
    m_comboGetSlot.SetCurSel(0);
    m_comboGetSlot.EnableWindow(mask.useGetSlot);
    m_comboPutPos.SetCurSel(0);
    m_comboPutPos.EnableWindow(mask.usePutPos);
    m_comboPutSlot.SetCurSel(0);
    m_comboPutSlot.EnableWindow(mask.usePutSlot);
}
void CRobotCmdTestDlg::AppendLogLineBatchBegin()
@@ -239,6 +270,8 @@
void CRobotCmdTestDlg::AppendLogLineRichStyled(const CString& content, COLORREF color /*= RGB(0, 0, 0)*/)
{
    if (!::IsWindow(GetSafeHwnd())) return;
    // 时间戳
    CString timestamp;
    CTime now = CTime::GetCurrentTime();
@@ -296,19 +329,73 @@
    m_editLog.SetSel(-1, 0);
}
void CRobotCmdTestDlg::OnCbnSelchangeComboCmdType()
void CRobotCmdTestDlg::UpdateSlotList(CComboBox* pComboDevice, CComboBox* pComboSlot)
{
    int nSel = m_comboCmdType.GetCurSel();
    if (nSel < 0) {
    if (pComboDevice == nullptr || pComboSlot == nullptr) {
        return;
    }
    CString str;
    m_comboCmdType.GetLBText(nSel, str);
    UpdateCommandInputUI(str);
    int nSelIndex = pComboDevice->GetCurSel();
    if (nSelIndex < 0) {
        return;
    }
    str.Format(_T("切换当前命令类型:%s"), str);
    AppendLogLineRichStyled(str, LOG_COLOR_NORMAL);
    CString strDeviceName;
    pComboDevice->GetLBText(nSelIndex, strDeviceName);
    int nMaxSlot = 1; // 默认槽位数
    auto it = g_mapDeviceSlotCount.find(strDeviceName);
    if (it != g_mapDeviceSlotCount.end()) {
        nMaxSlot = it->second;
    }
    else {
        CString strLog;
        strLog.Format(_T("设备 %s 未定义槽位数,使用默认值 1"), strDeviceName.GetString());
        AppendLogLineRichStyled(strLog, LOG_COLOR_WARNING);
    }
    // 清空并添加槽号
    pComboSlot->ResetContent();
    for (int i = 1; i <= nMaxSlot; ++i) {
        CString str;
        str.Format(_T("%d"), i);
        pComboSlot->AddString(str);
    }
    pComboSlot->SetCurSel(0);
    pComboSlot->EnableWindow(1 != nMaxSlot);
}
void CRobotCmdTestDlg::UpdateArmList(CComboBox* pComboDevice, CComboBox* pComboArm)
{
    if (pComboDevice == nullptr || pComboArm == nullptr) {
        return;
    }
    int nSelIndex = pComboDevice->GetCurSel();
    if (nSelIndex < 0) {
        return;
    }
    CString strDeviceName;
    pComboDevice->GetLBText(nSelIndex, strDeviceName);
    if (IsDualArmSupported(strDeviceName)) {
        pComboArm->EnableWindow(TRUE);
    }
    else {
        pComboArm->EnableWindow(FALSE);
    }
    pComboArm->SetCurSel(0);
}
bool CRobotCmdTestDlg::IsDualArmSupported(const CString& strDeviceName)
{
    // 注意匹配规则是否区分“-上产品”、“-下产品”等后缀
    if (strDeviceName.Find(_T("FLIP")) >= 0) return true;
    if (strDeviceName.Find(_T("Bonder1")) >= 0) return true;
    if (strDeviceName.Find(_T("Bonder2")) >= 0) return true;
    return false;
}
void CRobotCmdTestDlg::OnBnClickedButtonExecute()
@@ -333,7 +420,7 @@
    // 查找函数并执行
    auto it = m_mapCmdExec.find(cmdName);
    if (it != m_mapCmdExec.end() && nullptr != m_pEFEM) {
        int ret = it->second(1, armNo, getPos, getSlot, putPos, putSlot, [&](int code) -> int {
        int ret = it->second(1, armNo, getPos, putPos, getSlot, putSlot, [&](int code) -> int {
            if (code == WOK) {
                AppendLogLineRichStyled(_T("已收到Robot回应!"), LOG_COLOR_SUCCESS);
            }
@@ -360,3 +447,32 @@
        AppendLogLineRichStyled(log, LOG_COLOR_ERROR);
    }
}
void CRobotCmdTestDlg::OnSelchangeComboCmdType()
{
    int nSel = m_comboCmdType.GetCurSel();
    if (nSel < 0) {
        return;
    }
    CString str;
    m_comboCmdType.GetLBText(nSel, str);
    UpdateCommandInputUI(str);
    str.Format(_T("切换当前命令类型:%s"), str);
    AppendLogLineRichStyled(str, LOG_COLOR_NORMAL);
}
void CRobotCmdTestDlg::OnSelchangeComboGetPos()
{
    // TODO: 在此添加控件通知处理程序代码
    UpdateSlotList(&m_comboGetPos, &m_comboGetSlot);
    UpdateArmList(&m_comboGetPos, &m_comboArmNo);
}
void CRobotCmdTestDlg::OnSelchangeComboPutPos()
{
    // TODO: 在此添加控件通知处理程序代码
    UpdateSlotList(&m_comboPutPos, &m_comboPutSlot);
    UpdateArmList(&m_comboPutPos, &m_comboArmNo);
}
SourceCode/Bond/Servo/CRobotCmdTestDlg.h
@@ -35,8 +35,10 @@
protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    virtual BOOL OnInitDialog();
    afx_msg void OnCbnSelchangeComboCmdType();
    afx_msg void OnBnClickedButtonExecute();
    afx_msg void OnSelchangeComboCmdType();
    afx_msg void OnSelchangeComboGetPos();
    afx_msg void OnSelchangeComboPutPos();
    DECLARE_MESSAGE_MAP()
private:
@@ -46,6 +48,9 @@
    void TrimRichEditLineLimit(int maxLines = 100);
    void AppendLogLineRichStyled(const CString& content, COLORREF color = RGB(0, 0, 0));
    void HighlightAllMatches(const CString& strSearch, COLORREF clrHighlight = RGB(255, 165, 0));
    void UpdateSlotList(CComboBox* pComboDevice, CComboBox* pComboSlot);
    void UpdateArmList(CComboBox* pComboDevice, CComboBox* pComboArm);
    bool IsDualArmSupported(const CString& strDeviceName);
    // 控件
    CComboBox m_comboCmdType;
SourceCode/Bond/Servo/CVacuumBake.cpp
@@ -38,6 +38,301 @@
        addPin(SERVO::PinType::OUTPUT, _T("Out2"));
    }
    void CVacuumBake::initSteps()
    {
        CEquipment::initSteps();
        {
            // eq mode
            CEqModeStep* pStep = new CEqModeStep();
            pStep->setName(STEP_MODE);
            pStep->setWriteSignalDev(0xc40);
            pStep->setModeDev(0x15d7d);
            if (addStep(STEP_ID_EQMODE_CHANGED, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // eq status
            CEqStatusStep* pStep = new CEqStatusStep();
            pStep->setName(STEP_STATUS);
            pStep->setWriteSignalDev(0xc41);
            pStep->setStatusDev(0x15d59);
            if (addStep(STEP_ID_EQSTATUS_CHANGED, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // Eq Alarm
            static char* pszName[] = { STEP_ALARM_BLOCK1, STEP_ALARM_BLOCK2, STEP_ALARM_BLOCK3, STEP_ALARM_BLOCK4, STEP_ALARM_BLOCK5 };
            static int dev[5] = { 0x15f0e , 0x15f3b, 0x15f68, 0x15f95, 0x15fc2 };
            static int writeSignalDev[5] = { 0xc42, 0xc43, 0xc44, 0xc45, 0xc46 };
            static int addr[] = { STEP_ID_EQALARM1, STEP_ID_EQALARM2, STEP_ID_EQALARM3, STEP_ID_EQALARM4, STEP_ID_EQALARM5 };
            for (int i = 0; i < 5; i++) {
                CEqAlarmStep* pStep = new CEqAlarmStep();
                pStep->setName(pszName[i]);
                pStep->setWriteSignalDev(writeSignalDev[i]);
                pStep->setAlarmDev(dev[i]);
                if (addStep(addr[i], pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            CEqReadStep* pStep = new CEqReadStep(0x16b55, 538 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        decodeProcessDataReport((CStep*)pFrom, pszData, size);
                    }
                    return -1;
                });
            pStep->setName(STEP_PROCESS);
            pStep->setWriteSignalDev(0xc47);
            if (addStep(STEP_ID_PROCESS_DATA_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // eq cim mode change
            CEqCimModeChangeStep* pStep = new CEqCimModeChangeStep();
            pStep->setName(STEP_CIM_MODE_CHANGE);
            pStep->setWriteSignalDev(0xc60);
            pStep->setCimModeDev(0x2555);
            if (addStep(STEP_ID_CIMMODE_CHANGED_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // eq cim message cmd
            CEqCimMessageCmdStep* pStep = new CEqCimMessageCmdStep();
            pStep->setName(STEP_CIM_MESSAGE_CMD);
            pStep->setWriteSignalDev(0xc61);
            pStep->setCimMessageDev(0x2540);
            if (addStep(STEP_ID_CIM_MSG_SET_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // eq current recipe change
            CEqCurrentRecipeChangeStep* pStep = new CEqCurrentRecipeChangeStep();
            pStep->setName(STEP_EQ_RURRENT_RECIPE_CHANGE);
            pStep->setWriteSignalDev(0xc48);
            pStep->setDataDev(0x16850);
            if (addStep(STEP_ID_CURRENT_RECIPE_CHANGE_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // CIM Message Confirm
            // 要将int32的值拆分为两个short, 分别为msg id和panel id
            // 65538, 2Ϊmsg id, 1Ϊpanel id
            CEqReadIntStep* pStep = new CEqReadIntStep(__INT32, 0x15d80);
            pStep->setName(STEP_EQ_CIM_MESSAGE_CONFIRM);
            pStep->setWriteSignalDev(0xc49);
            if (addStep(STEP_ID_CIM_MSG_CONFIRM_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            CEqCimMessageClearStep* pStep = new CEqCimMessageClearStep();
            pStep->setName(STEP_CIM_MESSAGE_CLEAR);
            pStep->setWriteSignalDev(0xc62);
            pStep->setClearCimMessageDev(0x2553);
            if (addStep(STEP_ID_CIM_MSG_CLEAR_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            CEqDateTimeSetCmdStep* pStep = new CEqDateTimeSetCmdStep();
            pStep->setName(STEP_DATETIME_SET_CMD);
            pStep->setWriteSignalDev(0xc63);
            pStep->setDateTimeDev(0x2556);
            if (addStep(STEP_ID_DATETIME_SET_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            CEqModeChangeStep* pStep = new CEqModeChangeStep();
            pStep->setName(STEP_EQ_MODE_CHANGE);
            pStep->setWriteSignalDev(0xc65);
            pStep->setEqModeDev(0x255e);
            if (addStep(STEP_ID_EQMODE_CHANGE_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // 请求主配方列表的step
            CEqWriteStep* pStep = new CEqWriteStep();
            pStep->setName(STEP_EQ_MASTER_RECIPE_LIST_REQ);
            pStep->setWriteSignalDev(0xc66);
            pStep->setDataDev(0x2e4a);
            if (addStep(STEP_ID_MASTER_RECIPE_LIST_CMD_REPLY, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // master recipe list report
            CEqReadStep* pStep = new CEqReadStep(0x16955, 255 * 2,
                [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                    if (code == ROK && pszData != nullptr && size > 0) {
                        // 此处解释配方数据
                        short ret = decodeRecipeListReport(pszData, size);
                        pStep->setReturnCode(ret);
                    }
                    pStep->setReturnCode(MRLRC_OK);
                    return -1;
                });
            pStep->setName(STEP_EQ_MASTER_RECIPE_LIST);
            pStep->setWriteSignalDev(0xc4b);
            pStep->setReturnDev(0x37ad);
            if (addStep(STEP_ID_MASTER_RECIPE_LIST_REPORT, pStep) != 0) {
                delete pStep;
            }
        }
        {
            // 请求配方参数
            //CEqWriteStep* pStep = new CEqWriteStep();
            //pStep->setName(STEP_EQ_RECIPE_PARAMETER_REQ);
            //pStep->setWriteSignalDev(0xc67);
            //pStep->setDataDev(0x379b);
            //if (addStep(STEP_ID_RECIPE_PARAMETER_CMD_REPLY, pStep) != 0) {
            //    delete pStep;
            //}
        }
        {
            // recipe parameter report
            //CEqReadStep* pStep = new CEqReadStep(0x1aa54, 257 * 2,
            //    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
            //        if (code == ROK && pszData != nullptr && size > 0) {
            //            // 此处解释配方数据
            //            short ret = decodeRecipeParameterReport(pszData, size);
            //            pStep->setReturnCode(ret);
            //        }
            //        pStep->setReturnCode(MRLRC_OK);
            //        return -1;
            //    });
            //pStep->setName(STEP_EQ_RECIPE_PARAMETER);
            //pStep->setWriteSignalDev(0xc4c);
            //pStep->setReturnDev(m_nIndex == 0 ? 0x126c : 0x1bbc);
            //if (addStep(STEP_ID_RECIPE_PARAMETER_REPORT, pStep) != 0) {
            //    delete pStep;
            //}
        }
        // 使用CEqReadStep替换CEqJobEventStep
        {
            // Received Job Report Upstream #1~9
            char szBuffer[256];
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x14c90 + 320 * i, 320 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeReceivedJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_RECEIVED_JOB_UPSn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0xc00 + i);
                if (addStep(STEP_ID_RECIVE_JOB_UPS1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Sent Out Job Report Downstream #1~9
            char szBuffer[256];
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x14000 + 320 * i, 320 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeReceivedJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_SENT_OUT_JOB_DOWNSn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0xc0a + i);
                if (addStep(STEP_ID_SENT_OUT_JOB_DOWNS1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Fetched Out Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x15c31 + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeFetchedOutJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_FETCHED_OUT_JOBn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0xc23 + i);
                if (addStep(STEP_ID_FETCHED_OUT_JOB_REPORT1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
        {
            // Stored Job Report #1~15
            char szBuffer[256];
            for (int i = 0; i < 1; i++) {
                CEqReadStep* pStep = new CEqReadStep(0x15b23 + 18 * i, 18 * 2,
                    [&](void* pFrom, int code, const char* pszData, size_t size) -> int {
                        if (code == ROK && pszData != nullptr && size > 0) {
                            int port = (int)(__int64)((CEqReadStep*)pFrom)->getProp("Port");
                            if (port > 0) {
                                decodeStoredJobReport((CStep*)pFrom, port, pszData, size);
                            }
                        }
                        return -1;
                    });
                sprintf_s(szBuffer, "%s%d", STEP_EQ_STORED_JOBn, i + 1);
                pStep->setName(szBuffer);
                pStep->setProp("Port", (void*)(__int64)(i + 1));
                pStep->setWriteSignalDev(0xc14 + i);
                if (addStep(STEP_ID_STORE_JOB_REPORT1 + i, pStep) != 0) {
                    delete pStep;
                }
            }
        }
    }
    // 必须要实现的虚函数,在此初始化Slot信息
    void CVacuumBake::initSlots()
    {
SourceCode/Bond/Servo/CVacuumBake.h
@@ -15,6 +15,7 @@
        virtual void init();
        virtual void term();
        virtual void initPins();
        virtual void initSteps();
        virtual void initSlots();
        virtual void onTimer(UINT nTimerid);
        virtual void serialize(CArchive& ar);
SourceCode/Bond/Servo/Model.cpp
@@ -244,7 +244,7 @@
        // 状态映射
        static const char* STATUS_STR[] = {
            "Unknown", "Ready", "Running", "Error", "Abort", "Completed"
            "Unknown", "Ready", "Running", "Picking", "Placing", "Restoring", "Error", "Abort", "Completed"
        };
        auto state = pTask->getState();
        int index = static_cast<int>(state);
SourceCode/Bond/Servo/TransferManager.cpp
@@ -29,45 +29,6 @@
    }
}
// 任务状态转换成 int 类型
int TransferManager::statusToInt(TransferStatus status) {
    return static_cast<int>(status);
}
// int 类型转换成任务状态
TransferStatus TransferManager::intToStatus(int value) {
    switch (value) {
        case 0: return TransferStatus::Ready;
        case 1: return TransferStatus::Running;
        case 2: return TransferStatus::Error;
        case 3: return TransferStatus::Abort;
        case 4: return TransferStatus::Completed;
        default: return TransferStatus::Error;
    }
}
// 任务状态转换成字符串
std::string TransferManager::statusToString(TransferStatus status) {
    switch (status) {
        case TransferStatus::Ready:     return "Ready";
        case TransferStatus::Running:   return "Running";
        case TransferStatus::Error:     return "Error";
        case TransferStatus::Abort:     return "Abort";
        case TransferStatus::Completed: return "Completed";
        default:                        return "Unknown";
    }
}
// 字符串转换成任务状态
TransferStatus TransferManager::stringToStatus(const std::string& str) {
    if (str == "Ready")     return TransferStatus::Ready;
    if (str == "Running")   return TransferStatus::Running;
    if (str == "Error")     return TransferStatus::Error;
    if (str == "Abort")     return TransferStatus::Abort;
    if (str == "Completed") return TransferStatus::Completed;
    return TransferStatus::Error;
}
// 本地编码转为 UTF-8
std::string TransferManager::ansiToUtf8(const std::string& ansiStr) {
    // 1. ANSI → UTF-16
@@ -134,35 +95,46 @@
}
// 插入测试搬运记录
void TransferManager::insertTestTransferRecord() {
    if (nullptr != m_pDB) {
        int nCount = 10000;
void TransferManager::insertTestTransferRecord(int nCount /*=10000*/) {
    if (nullptr != m_pDB) {
        static const char* STATUS_STR[] = {
            "Unknown", "Ready", "Running", "Picking", "Placing",
            "Restoring", "Error", "Abort", "Completed"
        };
        auto formatTime = [](const std::tm& time) {
            char szTime[64];
            strftime(szTime, sizeof(szTime), "%Y-%m-%d %H:%M:%S", &time);
            return std::string(szTime);
        };
        std::time_t startTime = std::time(nullptr);
        for (int i = 0; i < nCount; ++i) {
            TransferData data;
            data.strClassID = "T-" + std::to_string(1000 + i);
            data.strStatus = statusToString(static_cast<TransferStatus>(i % 5));
            data.strStatus = STATUS_STR[i % 9];
            std::time_t now = std::time(nullptr) + i * 60;  // 每条记录间隔1分钟
            std::time_t baseTime = startTime + i * 60;
            std::time_t pickTime = baseTime + 60;
            std::time_t placeTime = pickTime + 60;
            std::time_t endTime = placeTime + 60;
            std::tm tmCreate = {}, tmPick = {}, tmPlace = {}, tmEnd = {};
            localtime_s(&tmCreate, &now);
            localtime_s(&tmPick, &(now += 60));
            localtime_s(&tmPlace, &(now += 60));
            localtime_s(&tmEnd, &(now += 60));
            localtime_s(&tmCreate, &baseTime);
            localtime_s(&tmPick, &pickTime);
            localtime_s(&tmPlace, &placeTime);
            localtime_s(&tmEnd, &endTime);
            char szTime[64];
            strftime(szTime, sizeof(szTime), "%Y-%m-%d %H:%M:%S", &tmCreate);
            data.strCreateTime = szTime;
            strftime(szTime, sizeof(szTime), "%Y-%m-%d %H:%M:%S", &tmPick);
            data.strPickTime = szTime;
            strftime(szTime, sizeof(szTime), "%Y-%m-%d %H:%M:%S", &tmPlace);
            data.strPlaceTime = szTime;
            strftime(szTime, sizeof(szTime), "%Y-%m-%d %H:%M:%S", &tmEnd);
            data.strEndTime = szTime;
            data.strCreateTime = formatTime(tmCreate);
            data.strPickTime = formatTime(tmPick);
            data.strPlaceTime = formatTime(tmPlace);
            data.strEndTime = formatTime(tmEnd);
            data.strDescription = "Mock transfer task " + std::to_string(i);
            int nRecordId = 0;
            addTransferRecord(data, nRecordId);
            if (!addTransferRecord(data, nRecordId)) {
                std::cerr << "[Error] 插入第 " << i << " 条记录失败" << std::endl;
            }
        }
        std::cout << "[Mock] 成功插入 " << nCount << " 条测试搬运记录。" << std::endl;
SourceCode/Bond/Servo/TransferManager.h
@@ -8,17 +8,6 @@
#include "Database.h"
/**
 * 任务状态枚举类型
 */
enum class TransferStatus {
    Ready = 0,
    Running,
    Error,
    Abort,
    Completed
};
/**
 * 搬运记录结构体
 */
struct TransferData {
@@ -51,7 +40,7 @@
    /**
     * 插入测试搬运记录
     */
    void insertTestTransferRecord();
    void insertTestTransferRecord(int nCount = 10000);
    /**
     * 终止数据库连接
@@ -157,10 +146,6 @@
    TransferManager& operator=(const TransferManager&) = delete;
    // 内联函数
    inline int statusToInt(TransferStatus status);
    inline TransferStatus intToStatus(int value);
    inline std::string statusToString(TransferStatus status);
    inline TransferStatus stringToStatus(const std::string& str);
    inline std::string ansiToUtf8(const std::string& ansiStr);
    inline std::string utf8ToAnsi(const std::string& utf8Str);