| | |
| | | |
| | | static unsigned short DATAID = 1; |
| | | |
| | | // Truncated SECS message logging to avoid overly long strings crashing UI/log |
| | | static void LogSecsMessageBrief(const char* tag, IMessage* pMessage, size_t maxLen = 1024) |
| | | { |
| | | if (pMessage == nullptr) return; |
| | | const char* msgStr = pMessage->toString(); |
| | | if (msgStr == nullptr) return; |
| | | std::string buf(msgStr); |
| | | if (buf.size() > maxLen) { |
| | | buf = buf.substr(0, maxLen) + "...<truncated>"; |
| | | } |
| | | LOGI("%s%s", tag, buf.c_str()); |
| | | } |
| | | |
| | | CHsmsActive::CHsmsActive() |
| | | { |
| | | m_listener = {}; |
| | |
| | | int nStream = (pHeader->stream & 0x7F); |
| | | |
| | | TRACE("收到消息 S%dF%d================\n", pHeader->stream & 0x7F, pHeader->function); |
| | | TRACE("Body:%s\n", pMessage->toString()); |
| | | LOGI("onRecvDataMessage(%s).", pMessage->toString()); |
| | | LogSecsMessageBrief("Body:", pMessage); |
| | | LogSecsMessageBrief("onRecvDataMessage:", pMessage); |
| | | |
| | | if (nStream == 5 && pHeader->function == 1) { |
| | | // S5F1 |
| | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsQueryAllStatusVariables() |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 11, ++m_nSystemByte); |
| | | // Host sends L:0 (empty list) to request all SVIDs. |
| | | pMessage->getBody()->addItem(); // empty list |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsQueryAllCollectionEvents() |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 23, ++m_nSystemByte); |
| | | // Host sends L:0 (empty list) to request all CEIDs. |
| | | pMessage->getBody()->addItem(); // empty list |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsQueryPPIDList() |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include <string> |
| | | #include <vector> |
| | | #include <map> |
| | |
| | | |
| | | |
| | | #define SVID_ControlState 600 |
| | | #define SVID_CurrentProcessState 700 |
| | | #define SVID_CJobSpace 5001 |
| | | #define SVID_PJobSpace 5002 |
| | | #define SVID_PJobQueued 5003 |
| | |
| | | // Deselect Request |
| | | int hsmsDeselectRequest(); |
| | | |
| | | // 建立通讯(S1F13) |
| | | // 建立通讯(S1F13) |
| | | int hsmsEstablishCommunications(); |
| | | |
| | | // Are You There |
| | |
| | | // Configure Spooling |
| | | int hsmsConfigureSpooling(std::map<unsigned int, std::set<unsigned int>>& spoolingConfig); |
| | | |
| | | // 发送或清空缓存的消息 |
| | | // 发送或清空缓存的消息 |
| | | int hsmsTransmitSpooledData(); |
| | | int hsmsPurgeSpooledData(); |
| | | |
| | | // 查询变量 |
| | | // 查询变量 |
| | | int hsmsSelectedEquipmentStatusRequest(unsigned int SVID); |
| | | int hsmsQueryAllStatusVariables(); // S1F11 |
| | | int hsmsQueryAllCollectionEvents(); // S1F23 |
| | | |
| | | // 查询PPID List |
| | | // 查询PPID List |
| | | int hsmsQueryPPIDList(); |
| | | |
| | | // S3F17 |
| | | // 卡匣动作请求 |
| | | // 卡匣动作请求 |
| | | int hsmsCarrierActionRequest(unsigned int DATAID, |
| | | const char* pszCarrierAction, |
| | | const char* pszCarrierId, |
| | |
| | | // S14F9 |
| | | int hsmsCreateControlJob(const char* pszControlJobId, std::vector<std::string>& processJobIds); |
| | | |
| | | // 通过的reply函数 |
| | | // 通过的reply函数 |
| | | void replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName); |
| | | |
| | | // reply ack0 |
| | |
| | | ON_BN_CLICKED(IDC_BUTTON_CTRL_ONLINE_LOCAL, &CEAPSimulatorDlg::OnBnClickedButtonCtrlOnlineLocal) |
| | | ON_BN_CLICKED(IDC_BUTTON_CTRL_ONLINE_REMOTE, &CEAPSimulatorDlg::OnBnClickedButtonCtrlOnlineRemote) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_CONTROL_STATE, &CEAPSimulatorDlg::OnBnClickedButtonQueryControlState) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_PROCESS_STATE, &CEAPSimulatorDlg::OnBnClickedButtonQueryProcessState) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_ALL_SVID, &CEAPSimulatorDlg::OnBnClickedButtonQueryAllSvid) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_ALL_CEID, &CEAPSimulatorDlg::OnBnClickedButtonQueryAllCeid) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | // S1F3 Query ProcessState (SVID=700) button |
| | | { |
| | | CRect rc(14 + 140 + 5, 136, 14 + 140 + 5 + 140, 136 + 14); // dialog units, same row offset |
| | | MapDialogRect(&rc); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S1F3_QueryProcessState"), |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rc.left, rc.top, rc.Width(), rc.Height(), |
| | | m_hWnd, (HMENU)IDC_BUTTON_QUERY_PROCESS_STATE, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn != nullptr) { |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | // S1F11 QueryAllSVID |
| | | { |
| | | CRect rc(14 + 140 + 5 + 140 + 5, 136, 14 + 140 + 5 + 140 + 5 + 140, 136 + 14); // dialog units, next row |
| | | MapDialogRect(&rc); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S1F11_QueryAllSVID"), |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rc.left, rc.top, rc.Width(), rc.Height(), |
| | | m_hWnd, (HMENU)IDC_BUTTON_QUERY_ALL_SVID, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn != nullptr) { |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | // S1F23 QueryAllCEID |
| | | { |
| | | CRect rc(14, 152, 14 + 140, 152 + 14); // dialog units, next row |
| | | MapDialogRect(&rc); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S1F23_QueryAllCEID"), |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rc.left, rc.top, rc.Width(), rc.Height(), |
| | | m_hWnd, (HMENU)IDC_BUTTON_QUERY_ALL_CEID, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn != nullptr) { |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | |
| | | SetDlgItemText(IDC_EDIT_IP, _T("127.0.0.1")); |
| | | SetDlgItemInt(IDC_EDIT_PORT, 7000); |
| | |
| | | } |
| | | if (GetDlgItem(IDC_BUTTON_QUERY_CONTROL_STATE) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_QUERY_CONTROL_STATE)->EnableWindow(enabled); |
| | | } |
| | | if (GetDlgItem(IDC_BUTTON_QUERY_PROCESS_STATE) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_QUERY_PROCESS_STATE)->EnableWindow(enabled); |
| | | } |
| | | if (GetDlgItem(IDC_BUTTON_QUERY_ALL_SVID) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_QUERY_ALL_SVID)->EnableWindow(enabled); |
| | | } |
| | | if (GetDlgItem(IDC_BUTTON_QUERY_ALL_CEID) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_QUERY_ALL_CEID)->EnableWindow(enabled); |
| | | } |
| | | } |
| | | |
| | |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsSelectedEquipmentStatusRequest(SVID_ControlState); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonQueryProcessState() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsSelectedEquipmentStatusRequest(SVID_CurrentProcessState); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonQueryAllSvid() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsQueryAllStatusVariables(); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonQueryAllCeid() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsQueryAllCollectionEvents(); |
| | | } |
| | |
| | | afx_msg void OnBnClickedButtonCtrlOnlineLocal(); |
| | | afx_msg void OnBnClickedButtonCtrlOnlineRemote(); |
| | | afx_msg void OnBnClickedButtonQueryControlState(); |
| | | afx_msg void OnBnClickedButtonQueryProcessState(); |
| | | afx_msg void OnBnClickedButtonQueryAllSvid(); |
| | | afx_msg void OnBnClickedButtonQueryAllCeid(); |
| | | }; |
| | |
| | | #define IDC_BUTTON_CTRL_ONLINE_LOCAL 1044 |
| | | #define IDC_BUTTON_CTRL_ONLINE_REMOTE 1045 |
| | | #define IDC_BUTTON_QUERY_CONTROL_STATE 1046 |
| | | #define IDC_BUTTON_QUERY_PROCESS_STATE 1047 |
| | | #define IDC_BUTTON_QUERY_ALL_SVID 1048 |
| | | #define IDC_BUTTON_QUERY_ALL_CEID 1049 |
| | | |
| | | // Next default values for new objects |
| | | // |
| | |
| | | #ifndef APSTUDIO_READONLY_SYMBOLS |
| | | #define _APS_NEXT_RESOURCE_VALUE 143 |
| | | #define _APS_NEXT_COMMAND_VALUE 32771 |
| | | #define _APS_NEXT_CONTROL_VALUE 1047 |
| | | #define _APS_NEXT_CONTROL_VALUE 1050 |
| | | #define _APS_NEXT_SYMED_VALUE 101 |
| | | #endif |
| | | #endif |
| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "CBonder.h" |
| | | |
| | | |
| | |
| | | CEquipment::term(); |
| | | } |
| | | |
| | | // 必须要实现的虚函数,在此初始化Pin列表 |
| | | // 必须要实现的虚函数,在此初始化Pin列表 |
| | | void CBonder::initPins() |
| | | { |
| | | // 加入Pin初始化代码 |
| | | // 加入Pin初始化代码 |
| | | LOGI("<CBonder>initPins"); |
| | | addPin(SERVO::PinType::INPUT, _T("In1")); |
| | | addPin(SERVO::PinType::INPUT, _T("In2")); |
| | |
| | | |
| | | { |
| | | // CIM Message Confirm |
| | | // 要将int32的值拆分为两个short, 分别为msg id和panel id |
| | | // 65538, 2Ϊmsg id, 1Ϊpanel id |
| | | // 要将int32的值拆分为两个short, 分别为msg id和panel id |
| | | // 65538, 2为msg id, 1为panel id |
| | | CEqReadIntStep* pStep = new CEqReadIntStep(__INT32, m_nIndex == 0 ? 0x9d80 : 0xdd80); |
| | | pStep->setName(STEP_EQ_CIM_MESSAGE_CONFIRM); |
| | | pStep->setWriteSignalDev(m_nIndex == 0 ? 0x349 : 0x649); |
| | |
| | | } |
| | | |
| | | { |
| | | // 请求主配方列表的step |
| | | // 请求主配方列表的step |
| | | CEqWriteStep* pStep = new CEqWriteStep(); |
| | | pStep->setName(STEP_EQ_MASTER_RECIPE_LIST_REQ); |
| | | pStep->setWriteSignalDev(m_nIndex == 0 ? 0x366 : 0x666); |
| | |
| | | CEqReadStep* pTmpStep = (CEqReadStep*)pFrom; |
| | | short ret = MRLRC_OK; |
| | | if (code == ROK && pszData != nullptr && size > 0) { |
| | | // 此处解释配方数据 |
| | | // 此处解释配方数据 |
| | | ret = decodeRecipeListReport(pszData, size); |
| | | } |
| | | pTmpStep->setReturnCode(ret); |
| | |
| | | } |
| | | |
| | | { |
| | | // 请求配方参数 |
| | | // 请求配方参数 |
| | | CEqWriteStep* pStep = new CEqWriteStep(); |
| | | pStep->setName(STEP_EQ_RECIPE_PARAMETER_REQ); |
| | | pStep->setWriteSignalDev(m_nIndex == 0 ? 0x367 : 0x667); |
| | |
| | | CEqReadStep* pTmpStep = (CEqReadStep*)pFrom; |
| | | short ret = MRLRC_OK; |
| | | if (code == ROK && pszData != nullptr && size > 0) { |
| | | // 此处解释配方数据 |
| | | // 此处解释配方数据 |
| | | ret = decodeRecipeParameterReport(pszData, size); |
| | | } |
| | | pTmpStep->setReturnCode(ret); |
| | |
| | | } |
| | | } |
| | | |
| | | // 使用CEqReadStep替换CEqJobEventStep |
| | | // 使用CEqReadStep替换CEqJobEventStep |
| | | { |
| | | // Received Job Report Upstream #1~9 |
| | | char szBuffer[256]; |
| | |
| | | } |
| | | } |
| | | |
| | | // 必须要实现的虚函数,在此初始化Slot信息 |
| | | // 必须要实现的虚函数,在此初始化Slot信息 |
| | | void CBonder::initSlots() |
| | | { |
| | | m_slot[0].enable(); |
| | |
| | | return 0; |
| | | } |
| | | |
| | | int CBonder::onProcessStateChanged(int slotNo, PROCESS_STATE state) |
| | | int CBonder::onProcessStateChanged(int slotNo, PROCESS_STATE prevState, PROCESS_STATE state) |
| | | { |
| | | CEquipment::onProcessStateChanged(slotNo, state); |
| | | CEquipment::onProcessStateChanged(slotNo, prevState, state); |
| | | |
| | | if (state == PROCESS_STATE::Complete) { |
| | | // 检查数据,当前两片玻璃,一片为G1, 一片为G2, 且pProcessData中的id能匹配G1或G2 |
| | | // 检查数据,当前两片玻璃,一片为G1, 一片为G2, 且pProcessData中的id能匹配G1或G2 |
| | | Lock(); |
| | | CGlass* pGlass2 = getGlassFromSlot(1); |
| | | CGlass* pGlass1 = getGlassFromSlot(2); |
| | | if (pGlass1 == nullptr || pGlass2 == nullptr) { |
| | | LOGE("<CBonder-%s>onProcessData,错误!不满足两片玻璃且分别为G1与G2的条件,请检查数据是否正确!", m_strName.c_str()); |
| | | LOGE("<CBonder-%s>onProcessData,错误!不满足两片玻璃且分别为G1与G2的条件,请检查数据是否正确!", m_strName.c_str()); |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | if (pGlass1->getBuddy() != nullptr) { |
| | | LOGE("<CBonder-%s>onProcessData,错误!玻璃较早前已被绑定,请检查数据是否正确!", m_strName.c_str()); |
| | | LOGE("<CBonder-%s>onProcessData,错误!玻璃较早前已被绑定,请检查数据是否正确!", m_strName.c_str()); |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | |
| | | if (pGlass1->getType() != MaterialsType::G1 || pGlass2->getType() != MaterialsType::G2) { |
| | | LOGE("<CBonder-%s>onProcessData,错误!两片玻璃未匹配,必须分别为G1和G2类型,请检查数据是否正确!", m_strName.c_str()); |
| | | LOGE("<CBonder-%s>onProcessData,错误!两片玻璃未匹配,必须分别为G1和G2类型,请检查数据是否正确!", m_strName.c_str()); |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | |
| | | pGlass1->setBuddy(pGlass2); |
| | | getSlot(0)->setContext(nullptr); |
| | | LOGE("<CBonder-%s>onProcessStateChanged,%s和%s已贴合!", m_strName.c_str(), |
| | | LOGE("<CBonder-%s>onProcessStateChanged,%s和%s已贴合!", m_strName.c_str(), |
| | | pGlass1->getID().c_str(), pGlass2->getID().c_str()); |
| | | Unlock(); |
| | | } |
| | |
| | | int i = 0, v; |
| | | |
| | | |
| | | // 1.校正对位延时 |
| | | // 1.校正对位延时 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("校正对位延时", "", this->getName().c_str(), v * 0.01f)); |
| | | params.push_back(CParam("校正对位延时", "", this->getName().c_str(), v * 0.01f)); |
| | | i += 2; |
| | | |
| | | // 2.保压时间 |
| | | // 2.保压时间 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("保压时间", "", this->getName().c_str(), v * 0.01f)); |
| | | params.push_back(CParam("保压时间", "", this->getName().c_str(), v * 0.01f)); |
| | | i += 2; |
| | | |
| | | // 3.腔体破真空延时 |
| | | // 3.腔体破真空延时 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("腔体破真空延时", "", this->getName().c_str(), v * 0.01f)); |
| | | params.push_back(CParam("腔体破真空延时", "", this->getName().c_str(), v * 0.01f)); |
| | | i += 2; |
| | | |
| | | // 4.腔体分子泵启动延时 |
| | | // 4.腔体分子泵启动延时 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("腔体分子泵启动延时", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("腔体分子泵启动延时", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 5.腔体贴附抽真空延时 |
| | | // 5.腔体贴附抽真空延时 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("腔体贴附抽真空延时", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("腔体贴附抽真空延时", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 6.加热等待延时 |
| | | // 6.加热等待延时 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("加热等待延时", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("加热等待延时", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 7.气囊压力设定 |
| | | // 7.气囊压力设定 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("气囊压力设定", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("气囊压力设定", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 8.气囊加压速率 |
| | | // 8.气囊加压速率 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("气囊加压速率", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("气囊加压速率", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 9.气囊泄压速率 |
| | | // 9.气囊泄压速率 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("气囊泄压速率", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("气囊泄压速率", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 10.贴附压力上限 |
| | | // 10.贴附压力上限 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("贴附压力上限", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("贴附压力上限", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 4; |
| | | |
| | | // 11.Z轴转矩速度设定 |
| | | // 11.Z轴转矩速度设定 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("上腔Z轴转矩速度设定", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("上腔Z轴转矩速度设定", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 12.上腔温度设定 |
| | | // 12.上腔温度设定 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("上腔温度设定", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("上腔温度设定", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 13.下腔温度设定 |
| | | // 13.下腔温度设定 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("下腔温度设定", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("下腔温度设定", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 14.上腔Z轴预贴合位速度 |
| | | // 14.上腔Z轴预贴合位速度 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("上腔Z轴预贴合位速度", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("上腔Z轴预贴合位速度", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 15.上腔Z轴贴附位速度 |
| | | // 15.上腔Z轴贴附位速度 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("上腔Z轴贴附位速度", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("上腔Z轴贴附位速度", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 16.上腔Z上腔加热位间距 |
| | | // 16.上腔Z上腔加热位间距 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("上腔Z上腔加热位间距", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("上腔Z上腔加热位间距", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 17.上腔贴附位压入量 |
| | | // 17.上腔贴附位压入量 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("上腔贴附位压入量", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("上腔贴附位压入量", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 18.上腔Z轴破真空距离 |
| | | // 18.上腔Z轴破真空距离 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("上腔Z轴破真空距离", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("上腔Z轴破真空距离", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 19.下顶Pin破真空距离 |
| | | // 19.下顶Pin破真空距离 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("下顶Pin破真空距离", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("下顶Pin破真空距离", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 20.下顶Pin加热位间距 |
| | | // 20.下顶Pin加热位间距 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("下顶Pin加热位间距", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("下顶Pin加热位间距", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 21.腔体真空泵真空规设定值 |
| | | params.push_back(CParam("腔体真空泵真空规设定值", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | // 21.腔体真空泵真空规设定值 |
| | | params.push_back(CParam("腔体真空泵真空规设定值", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | i += 4; |
| | | |
| | | // 22.腔体分子泵到达设定值 |
| | | params.push_back(CParam("腔体分子泵到达设定值", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | // 22.腔体分子泵到达设定值 |
| | | params.push_back(CParam("腔体分子泵到达设定值", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | i += 4; |
| | | |
| | | |
| | |
| | | int CBonder::parsingSVData(const char* pszData, size_t size, std::vector<CParam>& params) |
| | | { |
| | | /* |
| | | 1 工艺运行步骤 1Word 123456 |
| | | 2 气囊压力当前 2Word 12345.6 |
| | | 3 上腔压力合计 1Word 1234.56 |
| | | 4 管道真空规值 FLOAT 123.456 |
| | | 5 腔体真空规值 FLOAT 123.456 |
| | | 6 上腔温度1 1Word 12345.6 |
| | | 7 上腔温度2 1Word 12345.6 |
| | | 8 上腔温度3 1Word 12345.6 |
| | | 9 上腔温度4 1Word 12345.6 |
| | | 10 上腔温度5 1Word 12345.6 |
| | | 11 上腔温度6 1Word 12345.6 |
| | | 12 下腔温度1 1Word 12345.6 |
| | | 13 下腔温度2 1Word 12345.6 |
| | | 14 下腔温度3 1Word 12345.6 |
| | | 15 下腔温度4 1Word 12345.6 |
| | | 16 下腔温度5 1Word 12345.6 |
| | | 17 下腔温度6 1Word 12345.6 |
| | | 18 压合剩余时间 1Word 1234.56 |
| | | 1 工艺运行步骤 1Word 123456 |
| | | 2 气囊压力当前 2Word 12345.6 |
| | | 3 上腔压力合计 1Word 1234.56 |
| | | 4 管道真空规值 FLOAT 123.456 |
| | | 5 腔体真空规值 FLOAT 123.456 |
| | | 6 上腔温度1 1Word 12345.6 |
| | | 7 上腔温度2 1Word 12345.6 |
| | | 8 上腔温度3 1Word 12345.6 |
| | | 9 上腔温度4 1Word 12345.6 |
| | | 10 上腔温度5 1Word 12345.6 |
| | | 11 上腔温度6 1Word 12345.6 |
| | | 12 下腔温度1 1Word 12345.6 |
| | | 13 下腔温度2 1Word 12345.6 |
| | | 14 下腔温度3 1Word 12345.6 |
| | | 15 下腔温度4 1Word 12345.6 |
| | | 16 下腔温度5 1Word 12345.6 |
| | | 17 下腔温度6 1Word 12345.6 |
| | | 18 压合剩余时间 1Word 1234.56 |
| | | */ |
| | | |
| | | ASSERT(pszData); |
| | |
| | | int i = 0, v; |
| | | |
| | | |
| | | // 1.工艺运行步骤 |
| | | // 1.工艺运行步骤 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("工艺运行步骤", "", this->getName().c_str(), v)); |
| | | params.push_back(CParam("工艺运行步骤", "", this->getName().c_str(), v)); |
| | | i += 2; |
| | | |
| | | // 2.气囊压力当前 |
| | | // 2.气囊压力当前 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("气囊压力当前", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("气囊压力当前", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 4; |
| | | |
| | | // 3.上腔压力合计 |
| | | // 3.上腔压力合计 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("上腔压力合计", "", this->getName().c_str(), ((short)v) * 0.01f)); |
| | | params.push_back(CParam("上腔压力合计", "", this->getName().c_str(), ((short)v) * 0.01f)); |
| | | i += 2; |
| | | |
| | | // 4.管道真空规值 |
| | | params.push_back(CParam("管道真空规值", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | // 4.管道真空规值 |
| | | params.push_back(CParam("管道真空规值", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | i += 4; |
| | | |
| | | // 5.腔体真空规值 |
| | | params.push_back(CParam("腔体真空规值", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | // 5.腔体真空规值 |
| | | params.push_back(CParam("腔体真空规值", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | i += 4; |
| | | |
| | | // 6.上腔温度1 |
| | | // 6.上腔温度1 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("上腔温度1", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("上腔温度1", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 7.上腔温度2 |
| | | // 7.上腔温度2 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("上腔温度2", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("上腔温度2", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 8.上腔温度3 |
| | | // 8.上腔温度3 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("上腔温度3", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("上腔温度3", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 9.上腔温度4 |
| | | // 9.上腔温度4 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("上腔温度4", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("上腔温度4", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 10.上腔温度5 |
| | | // 10.上腔温度5 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("上腔温度5", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("上腔温度5", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 11.上腔温度6 |
| | | // 11.上腔温度6 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("上腔温度6", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("上腔温度6", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 12.下腔温度1 |
| | | // 12.下腔温度1 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("下腔温度1", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("下腔温度1", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 13.下腔温度2 |
| | | // 13.下腔温度2 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("下腔温度2", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("下腔温度2", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 14.下腔温度3 |
| | | // 14.下腔温度3 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("下腔温度3", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("下腔温度3", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 15.下腔温度4 |
| | | // 15.下腔温度4 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("下腔温度4", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("下腔温度4", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 16.下腔温度5 |
| | | // 16.下腔温度5 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("下腔温度5", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("下腔温度5", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 17.下腔温度6 |
| | | // 17.下腔温度6 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("下腔温度6", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("下腔温度6", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 18.加热剩余时间 |
| | | // 18.加热剩余时间 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("加热剩余时间", "", this->getName().c_str(), v * 0.01f)); |
| | | params.push_back(CParam("加热剩余时间", "", this->getName().c_str(), v * 0.01f)); |
| | | i += 2; |
| | | |
| | | // 19.压合剩余时间 |
| | | // 19.压合剩余时间 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("压合剩余时间", "", this->getName().c_str(), v * 0.01f)); |
| | | params.push_back(CParam("压合剩余时间", "", this->getName().c_str(), v * 0.01f)); |
| | | i += 2; |
| | | |
| | | return (int)params.size(); |
| | |
| | | virtual void getAttributeVector(CAttributeVector& attrubutes); |
| | | virtual int recvIntent(CPin* pPin, CIntent* pIntent); |
| | | virtual int onProcessData(CProcessData* pProcessData); |
| | | virtual int onProcessStateChanged(int slotNo, PROCESS_STATE state); |
| | | virtual int onProcessStateChanged(int slotNo, PROCESS_STATE prevState, PROCESS_STATE state); |
| | | virtual int getIndexerOperationModeBaseValue(); |
| | | virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms); |
| | | virtual int parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& parsms); |
| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "CEquipment.h" |
| | | #include "ToolUnits.h" |
| | | #include <regex> |
| | |
| | | void CEquipment::getProperties(std::vector<std::pair<std::string, std::string>>& container) |
| | | { |
| | | container.clear(); |
| | | // 示例:将一些属性添加到容器 |
| | | // 示例:将一些属性添加到容器 |
| | | container.push_back(std::make_pair("DeviceName", "ServoMotor")); |
| | | container.push_back(std::make_pair("SerialNumber", "123456789")); |
| | | container.push_back(std::make_pair("Version", "1.0")); |
| | |
| | | { |
| | | if (nSlotNo <= 0 || nSlotNo > 8) return; |
| | | |
| | | const auto prevState = m_processState[nSlotNo - 1]; |
| | | m_processState[nSlotNo - 1] = state; |
| | | onProcessStateChanged(nSlotNo, m_processState[nSlotNo - 1]); |
| | | onProcessStateChanged(nSlotNo, prevState, m_processState[nSlotNo - 1]); |
| | | |
| | | if (m_listener.onProcessStateChanged != nullptr) { |
| | | m_listener.onProcessStateChanged(this, nSlotNo, m_processState[nSlotNo - 1]); |
| | | m_listener.onProcessStateChanged(this, nSlotNo, prevState, m_processState[nSlotNo - 1]); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | void CEquipment::onTimer(UINT nTimerid) |
| | | { |
| | | // 每隔一秒,检查一下ALIVE状态 |
| | | // 每隔一秒,检查一下ALIVE状态 |
| | | |
| | | static int tick = 0; |
| | | tick++; |
| | |
| | | } |
| | | } |
| | | |
| | | // 梳理各玻璃之间的绑定关系 |
| | | // 梳理各玻璃之间的绑定关系 |
| | | /* |
| | | Lock(); |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | |
| | | CGlass* pBudy = (CGlass*)m_slot[j].getContext(); |
| | | if (pBudy != nullptr && strBuddyId.compare(pBudy->getID()) == 0) { |
| | | pGlass->setBuddy(pBudy); |
| | | TRACE("绑定关系: %s <- %s\n", pGlass->getID().c_str(), pBudy->getID().c_str()); |
| | | TRACE("绑定关系: %s <- %s\n", pGlass->getID().c_str(), pBudy->getID().c_str()); |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | */ |
| | | |
| | | // 连接信号解释和保存 |
| | | // 连接信号解释和保存 |
| | | BOOL bFlag; |
| | | int index = 0; |
| | | for (int i = 0; i < 8; i++) { |
| | |
| | | } |
| | | |
| | | |
| | | // 其它信号及响应 |
| | | // 其它信号及响应 |
| | | index = 0x540; |
| | | |
| | | |
| | |
| | | m_alive.flag = bFlag; |
| | | m_alive.count = 0; |
| | | |
| | | // ״̬ |
| | | // 状态 |
| | | if (!m_alive.alive) { |
| | | m_alive.alive = TRUE; |
| | | if (m_listener.onAlive != nullptr) { |
| | |
| | | } |
| | | |
| | | |
| | | // 以下根据信号做流程处理 |
| | | // 以下根据信号做流程处理 |
| | | for (int i = 0; i < 7; i++) { |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_EQMODE_CHANGED + i, pszData, size); |
| | | } |
| | |
| | | } |
| | | |
| | | |
| | | // 配方改变 |
| | | // 配方改变 |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_CURRENT_RECIPE_CHANGE_REPORT, pszData, size); |
| | | |
| | | // 主配方上报 |
| | | // 主配方上报 |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_MASTER_RECIPE_LIST_REPORT, pszData, size); |
| | | |
| | | // 配方参数 |
| | | // 配方参数 |
| | | CHECK_WRITE_STEP_SIGNAL(STEP_ID_RECIPE_PARAMETER_CMD_REPLY, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_RECIPE_PARAMETER_REPORT, pszData, size); |
| | | |
| | |
| | | else if (isCimMessageConfirmStep(pStep)) { |
| | | SERVO::CEqReadIntStep* pEqReadIntStep = (SERVO::CEqReadIntStep*)pStep; |
| | | int value = pEqReadIntStep->getValue(); |
| | | // 此处将value按高低位拆分为message id和panel no. |
| | | // 可能还需要上报到cim |
| | | // 此处将value按高低位拆分为message id和panel no. |
| | | // 可能还需要上报到cim |
| | | short msgId, panelNo; |
| | | msgId = (value & 0xffff0000 >> 16); |
| | | panelNo = (value & 0xffff); |
| | |
| | | m_listener.onVcrEventReport(this, pVcrEventReport); |
| | | } |
| | | |
| | | // 0426, 先固定返回1(OK) |
| | | // 0426, 先固定返回1(OK) |
| | | pEqVcrEventStep->setReturnCode(1); |
| | | return 1; |
| | | } |
| | |
| | | |
| | | CPin* CEquipment::addPin(PinType type, char* pszName) |
| | | { |
| | | // 不允许名字添加重复的pin |
| | | // 不允许名字添加重复的pin |
| | | CPin* pPin = getPin(pszName); |
| | | if (pPin != nullptr) return nullptr; |
| | | |
| | | |
| | | // 添加到Pin列表,看是输入pin或输出pin |
| | | // 添加到Pin列表,看是输入pin或输出pin |
| | | if (type == PinType::INPUT) { |
| | | pPin = new CPin(this, type, pszName); |
| | | m_inputPins.push_back(pPin); |
| | |
| | | CEquipment* pFromEq = pFromPin->getEquipment(); |
| | | ASSERT(pFromEq); |
| | | |
| | | LOGD("<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(), |
| | |
| | | |
| | | |
| | | |
| | | // 以下解释处理数据 |
| | | // 以下解释处理数据 |
| | | int code = pIntent->getCode(); |
| | | |
| | | |
| | | // 测试 |
| | | // 测试 |
| | | if (code == FLOW_TEST) { |
| | | AfxMessageBox(pIntent->getMsg()); |
| | | } |
| | |
| | | return -1; |
| | | } |
| | | |
| | | // 找到指定的glass id, |
| | | // 找到指定的glass id, |
| | | Lock(); |
| | | CGlass* pContext = nullptr; |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | |
| | | CGlass* pBuddy = pGlass->getBuddy(); |
| | | if (pBuddy != nullptr) pBuddy->addPath(m_nID, getSlotUnit(putSlot), putSlot); |
| | | m_slot[putSlot - 1].setContext(pGlass); |
| | | pGlass->release(); // tempFetchOut需要调用一次release |
| | | pGlass->release(); // tempFetchOut需要调用一次release |
| | | Unlock(); |
| | | |
| | | /* |
| | |
| | | return -1; |
| | | } |
| | | |
| | | LOGI("<CEquipment-%s>准备设置DispatchingMode<%d>", m_strName.c_str(), (int)mode); |
| | | LOGI("<CEquipment-%s>准备设置DispatchingMode<%d>", m_strName.c_str(), (int)mode); |
| | | if (onWritedBlock != nullptr) { |
| | | pStep->writeShort((short)mode, onWritedBlock); |
| | | } |
| | | else { |
| | | pStep->writeShort((short)mode, [&, mode](int code) -> int { |
| | | if (code == WOK) { |
| | | LOGI("<CEquipment-%s>设置DispatchingMode成功.", m_strName.c_str()); |
| | | LOGI("<CEquipment-%s>设置DispatchingMode成功.", m_strName.c_str()); |
| | | } |
| | | else { |
| | | LOGE("<CEquipment-%s>设置DispatchingMode失败,code:%d", m_strName.c_str(), code); |
| | | LOGE("<CEquipment-%s>设置DispatchingMode失败,code:%d", m_strName.c_str(), code); |
| | | } |
| | | |
| | | return 0; |
| | |
| | | } |
| | | |
| | | unsigned short operationMode = (unsigned short)((unsigned short)mode + getIndexerOperationModeBaseValue()); |
| | | LOGI("<CEquipment-%s>准备设置indexerOperationMode<%d>", m_strName.c_str(), (int)mode); |
| | | LOGI("<CEquipment-%s>准备设置indexerOperationMode<%d>", m_strName.c_str(), (int)mode); |
| | | pStep->writeShort(operationMode, [&, pStep, mode, onWritedRetBlock](int code) -> int { |
| | | int retCode = 0; |
| | | if (code == WOK) { |
| | | LOGI("<CEquipment-%s>设置indexerOperationMode成功.", m_strName.c_str()); |
| | | LOGI("<CEquipment-%s>设置indexerOperationMode成功.", m_strName.c_str()); |
| | | const char* pszRetData = nullptr; |
| | | pStep->getReturnData(pszRetData); |
| | | ASSERT(pszRetData); |
| | | retCode = (unsigned int)CToolUnits::toInt16(pszRetData); |
| | | LOGI("<CEquipment-%s>返回值: %d", m_strName.c_str(), retCode); |
| | | LOGI("<CEquipment-%s>返回值: %d", m_strName.c_str(), retCode); |
| | | } |
| | | else { |
| | | LOGE("<CEquipment-%s>设置indexerOperationMode失败,code:%d", m_strName.c_str(), code); |
| | | LOGE("<CEquipment-%s>设置indexerOperationMode失败,code:%d", m_strName.c_str(), code); |
| | | } |
| | | |
| | | if (onWritedRetBlock != nullptr) { |
| | |
| | | return -1; |
| | | } |
| | | |
| | | LOGI("<CEquipment-%s>正在请求单元<%d>主配方列表", m_strName.c_str(), unitNo); |
| | | LOGI("<CEquipment-%s>正在请求单元<%d>主配方列表", m_strName.c_str(), unitNo); |
| | | m_recipesManager.setOnSyncingStateChanged(block); |
| | | if (m_recipesManager.syncing() != 0) { |
| | | return -2; |
| | | } |
| | | pStep->writeShort(unitNo, [&, unitNo](int code) -> int { |
| | | if (code == WOK) { |
| | | LOGI("<CEquipment-%s>请求单元<%d>主配方列表成功,正在等待数据.", m_strName.c_str(), unitNo); |
| | | LOGI("<CEquipment-%s>请求单元<%d>主配方列表成功,正在等待数据.", m_strName.c_str(), unitNo); |
| | | } |
| | | else { |
| | | m_recipesManager.syncFailed(); |
| | | LOGE("<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; |
| | |
| | | |
| | | int CEquipment::recipeParameterRequest(short masterRecipeId, short localRecipeId, short unitNo, ONSYNCINGSTATECHANGED block) |
| | | { |
| | | LOGI("<CEquipment-%s>正在请求单元<%d>主配参数列表", m_strName.c_str(), unitNo); |
| | | LOGI("<CEquipment-%s>正在请求单元<%d>主配参数列表", m_strName.c_str(), unitNo); |
| | | m_recipesManager.setOnSyncingStateChanged(block); |
| | | if (m_recipesManager.syncing() != 0) { |
| | | return -2; |
| | |
| | | |
| | | pStep->writeDataEx(szBuffer, 14 * 2, [&, unitNo](int code) -> int { |
| | | if (code == WOK) { |
| | | LOGI("<CEquipment-%s>请求单元<%d>主配方参数列表成功,正在等待数据.", m_strName.c_str(), unitNo); |
| | | LOGI("<CEquipment-%s>请求单元<%d>主配方参数列表成功,正在等待数据.", m_strName.c_str(), unitNo); |
| | | } |
| | | else { |
| | | m_recipesManager.syncFailed(); |
| | | LOGE("<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; |
| | |
| | | int nRet = processData.unserialize(&pszData[0], (int)size); |
| | | if (nRet < 0) return nRet; |
| | | |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | unsigned int weight = 201; |
| | | CAttributeVector& attrubutes = pStep->attributeVector(); |
| | | processData.getAttributeVector(attrubutes, weight); |
| | |
| | | |
| | | |
| | | |
| | | // 找到玻璃,关联数据 |
| | | // 找到玻璃,关联数据 |
| | | CGlass* pGlass = this->getGlassWithCassette(processData.getCassetteSequenceNo(), |
| | | processData.getJobSequenceNo()); |
| | | if (pGlass == nullptr) { |
| | | LOGE("<CEquipment-%s>找不到对应Glass, 关联工艺参数失败。CassetteSequenceNo:%d/%d", |
| | | LOGE("<CEquipment-%s>找不到对应Glass, 关联工艺参数失败。CassetteSequenceNo:%d/%d", |
| | | this->getName().c_str(), |
| | | processData.getCassetteSequenceNo(), |
| | | processData.getJobSequenceNo()); |
| | |
| | | std::vector<CParam> tempParams; |
| | | this->parsingProcessData((const char*)rawData.data(), rawData.size(), tempParams); |
| | | int n = processData.getTotalParameter(); |
| | | std::vector<CParam> params(tempParams.begin(), tempParams.begin() + min(n, (int)tempParams.size())); |
| | | std::vector<CParam> params(tempParams.begin(), tempParams.begin() + (std::min)(n, (int)tempParams.size())); |
| | | pGlass->addParams(params); |
| | | if (m_listener.onProcessDataReport != nullptr) { |
| | | m_listener.onProcessDataReport(this, params); |
| | | } |
| | | |
| | | // 关联的Glass也要更新 |
| | | // 关联的Glass也要更新 |
| | | CGlass* pBuddy = pGlass->getBuddy(); |
| | | LOGI("<Equipment-%s>decodeProcessDataReport pBuddy=%x %s", getName().c_str(), pBuddy, pGlass->getID().c_str()); |
| | | if (pBuddy != nullptr) { |
| | | LOGI("<Equipment-%s>decodeProcessDataReport addParams pBuddy=%x %s", getName().c_str(), pBuddy, pGlass->getID().c_str()); |
| | | pBuddy->addParams(params); |
| | | if (m_listener.onProcessDataReport != nullptr) { |
| | | m_listener.onProcessDataReport(this, params); |
| | | } |
| | | } |
| | | |
| | | return nRet; |
| | |
| | | int nRet = jobDataS.unserialize(&pszData[0], (int)size); |
| | | if (nRet < 0) return nRet; |
| | | |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | unsigned int weight = 201; |
| | | CAttributeVector& attrubutes = pStep->attributeVector(); |
| | | jobDataS.getAttributeVector(attrubutes, weight); |
| | |
| | | LOGI("<CEquipment-%s>onReceivedJob.", m_strName.c_str()); |
| | | |
| | | |
| | | // 可以在此更新JobDataS数据了 |
| | | // 可以在此更新JobDataS数据了 |
| | | int nRet = ((CArm*)m_pArm)->glassUpdateJobDataS(pJobDataS); |
| | | if (nRet < 0) { |
| | | LOGE("<CEquipment-%s>onReceivedJob,更新JobDataS失败,glassUpdateJobDataS返回%d", |
| | | LOGE("<CEquipment-%s>onReceivedJob,更新JobDataS失败,glassUpdateJobDataS返回%d", |
| | | m_strName.c_str(), nRet); |
| | | } |
| | | |
| | |
| | | int nRet = jobDataS.unserialize(&pszData[0], (int)size); |
| | | if (nRet < 0) return nRet; |
| | | |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | unsigned int weight = 201; |
| | | CAttributeVector& attrubutes = pStep->attributeVector(); |
| | | jobDataS.getAttributeVector(attrubutes, weight); |
| | |
| | | index += sizeof(short); |
| | | |
| | | |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | unsigned int weight = 201; |
| | | pStep->addAttribute(new CAttribute("UnitOrPort", |
| | | std::to_string(unitOrPort).c_str(), "", weight++)); |
| | |
| | | return fetchedOutJob(port, pJobDataB); |
| | | } |
| | | |
| | | // 数据异常,处理或显示 |
| | | // 数据异常,处理或显示 |
| | | LOGI("<CEquipment-%s>onFetchedOutJob Error.ort:%d|GlassId:%s", |
| | | m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); |
| | | return -1; |
| | |
| | | index += sizeof(short); |
| | | |
| | | |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | unsigned int weight = 201; |
| | | pStep->addAttribute(new CAttribute("UnitOrPort", |
| | | std::to_string(unitOrPort).c_str(), "", weight++)); |
| | |
| | | vcrEventReport.getGlassId().c_str()); |
| | | |
| | | |
| | | // 更新Glass的ID |
| | | // 更新Glass的ID |
| | | CGlass* pGlass = getGlassWithCassette(vcrEventReport.getCassetteSequenceNo(), |
| | | vcrEventReport.getJobSequenceNo()); |
| | | if (pGlass != nullptr) { |
| | |
| | | } |
| | | |
| | | |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | unsigned int weight = 201; |
| | | CAttributeVector& attrubutes = pStep->attributeVector(); |
| | | vcrEventReport.getAttributeVector(attrubutes, weight); |
| | | |
| | | |
| | | // 0426, 先固定返回1(OK) |
| | | // 0426, 先固定返回1(OK) |
| | | ((CReadStep*)pStep)->setReturnCode((short)VCR_Reply_Code::OK); |
| | | |
| | | |
| | |
| | | index += 256 * 2; |
| | | |
| | | |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | unsigned int weight = 201; |
| | | pStep->addAttribute(new CAttribute("CassetteNo", |
| | | std::to_string(cassetteNo).c_str(), "", weight++)); |
| | |
| | | strPanelGradeData.c_str(), "", weight++)); |
| | | |
| | | |
| | | // 更新检测结果 |
| | | // 更新检测结果 |
| | | CGlass* pGlass = getGlassWithCassette(cassetteNo, jobSequenceNo); |
| | | if (pGlass == nullptr) { |
| | | LOGE("<CEquipment-%s>更新Panel Data失败,找不到对应的Glass.cassetteNo=%d, jobSequenceNo=%d", |
| | | LOGE("<CEquipment-%s>更新Panel Data失败,找不到对应的Glass.cassetteNo=%d, jobSequenceNo=%d", |
| | | getName().c_str(), cassetteNo, jobSequenceNo); |
| | | return -1; |
| | | } |
| | |
| | | |
| | | |
| | | |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | unsigned int weight = 201; |
| | | pStep->addAttribute(new CAttribute("CassetteSequenceNo", |
| | | (std::to_string(cassetteSequenceNo)).c_str(), "", weight++)); |
| | |
| | | |
| | | CGlass* pGlass = getGlassFromSlot(slotNo); |
| | | if (pGlass == nullptr) { |
| | | LOGE("<CEquipment-%s>decodeJobProcessStartReport, 找不到对应glass", getName().c_str()); |
| | | LOGE("<CEquipment-%s>decodeJobProcessStartReport, 找不到对应glass", getName().c_str()); |
| | | } |
| | | if (slotNo <= 0 || slotNo > 8) return -1; |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | unsigned int weight = 201; |
| | | pStep->addAttribute(new CAttribute("CassetteNo", |
| | | std::to_string(cassetteNo).c_str(), "", weight++)); |
| | |
| | | } |
| | | |
| | | if (pGlass == nullptr) { |
| | | LOGE("<CEquipment-%s>decodeJobProcessEndReport, 找不到对应glass", getName().c_str()); |
| | | LOGE("<CEquipment-%s>decodeJobProcessEndReport, 找不到对应glass", getName().c_str()); |
| | | } |
| | | else { |
| | | CJobDataS* pJs = pGlass->getJobDataS(); |
| | |
| | | pGlass->processEnd(m_nID, getSlotUnit(slotNo)); |
| | | } |
| | | else { |
| | | LOGE("<CEquipment-%s>decodeJobProcessEndReport, jobSequenceNo或jobSequenceNo不匹配", |
| | | LOGE("<CEquipment-%s>decodeJobProcessEndReport, jobSequenceNo或jobSequenceNo不匹配", |
| | | getName().c_str()); |
| | | } |
| | | } |
| | |
| | | |
| | | |
| | | |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | // 缓存Attribute,用于调试时显示信息 |
| | | unsigned int weight = 201; |
| | | pStep->addAttribute(new CAttribute("CassetteNo", |
| | | std::to_string(cassetteNo).c_str(), "", weight++)); |
| | |
| | | LOGI("<CEquipment-%s>onPreStoredJob:port:%d|GlassId:%s", |
| | | m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); |
| | | |
| | | // 当前要存片,之前肯定有拔片,因此片子在Arm那里 |
| | | // 当前要存片,之前肯定有拔片,因此片子在Arm那里 |
| | | CGlass* pGlass = ((CArm*)m_pArm)->getGlassFromSlot(1); |
| | | if (pGlass == nullptr) { |
| | | LOGE("<CFliper-%s>onPreStoredJob,缓存中没有找到对应的Glass(CassetteSequenceNo:%d, JobSequenceNo:%d),请检查数据,注意风险。", m_strName.c_str(), |
| | | LOGE("<CFliper-%s>onPreStoredJob,缓存中没有找到对应的Glass(CassetteSequenceNo:%d, JobSequenceNo:%d),请检查数据,注意风险。", m_strName.c_str(), |
| | | pJobDataB->getCassetteSequenceNo(), pJobDataB->getJobSequenceNo()); |
| | | return FALSE; |
| | | } |
| | |
| | | CJobDataS* pJobDataS = pGlass->getJobDataS(); |
| | | ASSERT(pJobDataS); |
| | | if (!compareJobData(pJobDataB, pJobDataS)) { |
| | | LOGE("<CEquipemnt-%s>onPreStoredJob,JobData数据不匹配(JobDataB(%d, %d),JobDataS(%d, %d)), 注意排查风险!", m_strName.c_str(), |
| | | LOGE("<CEquipemnt-%s>onPreStoredJob,JobData数据不匹配(JobDataB(%d, %d),JobDataS(%d, %d)), 注意排查风险!", m_strName.c_str(), |
| | | pJobDataB->getCassetteSequenceNo(), pJobDataB->getJobSequenceNo(), |
| | | pJobDataS->getCassetteSequenceNo(), pJobDataS->getJobSequenceNo()); |
| | | return FALSE; |
| | | } |
| | | |
| | | // 如果没有可用位置,报错 |
| | | // 如果没有可用位置,报错 |
| | | Lock(); |
| | | CSlot* pSlot = getSlot(putSlot - 1); |
| | | ASSERT(pSlot); |
| | | if (pSlot->getContext() != nullptr) { |
| | | Unlock(); |
| | | LOGE("<CEquipemnt-%s>onPreStoredJob,指定slot(port:%d)有料,请注意风险!", m_strName.c_str(), port); |
| | | LOGE("<CEquipemnt-%s>onPreStoredJob,指定slot(port:%d)有料,请注意风险!", m_strName.c_str(), port); |
| | | return FALSE; |
| | | } |
| | | Unlock(); |
| | |
| | | return storedJob(port, pJobDataB, putSlot); |
| | | } |
| | | |
| | | // 数据异常,处理或显示 |
| | | // 数据异常,处理或显示 |
| | | LOGI("<CEquipment-%s>onStoredJob Error.port:%d|GlassId:%s", |
| | | m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); |
| | | return -1; |
| | |
| | | } |
| | | |
| | | /* |
| | | * 当从CC-Link检测到设备Send Able为On时调用此函数 |
| | | * 可能会多次重复调用(根据扫描频率), 注意防呆 |
| | | * 当从CC-Link检测到设备Send Able为On时调用此函数 |
| | | * 可能会多次重复调用(根据扫描频率), 注意防呆 |
| | | */ |
| | | int CEquipment::onSendAble(int port) |
| | | { |
| | |
| | | return 0; |
| | | } |
| | | |
| | | int CEquipment::onProcessStateChanged(int nSlotNo, PROCESS_STATE state) |
| | | int CEquipment::onProcessStateChanged(int nSlotNo, PROCESS_STATE prevState, PROCESS_STATE state) |
| | | { |
| | | return 0; |
| | | } |
| | |
| | | { |
| | | return m_svDatas; |
| | | } |
| | | } |
| | | } |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include "Log.h" |
| | | #include "ServoCommo.h" |
| | | #include "CCLinkIEControl.h" |
| | |
| | | typedef std::function<void(void* pEiuipment, void* pReport)> ONVCREVENTREPORT; |
| | | typedef std::function<BOOL(void* pEiuipment, int port, CJobDataB* pJobDataB)> ONPREFETCHEDOUTJOB; |
| | | typedef std::function<BOOL(void* pEiuipment, int port, CJobDataB* pJobDataB, short& putSlot)> ONPRESTOREDJOB; |
| | | typedef std::function<void(void* pEiuipment, int nSlotNo, PROCESS_STATE state)> ONPROCESSSTATE; |
| | | typedef std::function<void(void* pEiuipment, int nSlotNo, PROCESS_STATE prevState, PROCESS_STATE state)> ONPROCESSSTATE; |
| | | typedef std::function<void(void* pEiuipment, short scanMap, short downMap)> ONMAPMISMATCH; |
| | | typedef std::function<void(void* pEiuipment, short status, __int64 data)> ONPORTSTATUSCHANGED; |
| | | typedef std::function<void(void* pEiuipment, const std::vector<CParam>& params)> ONPROCESSDATAREPORT; |
| | | |
| | | typedef struct _EquipmentListener |
| | | { |
| | |
| | | ONPORTSTATUSCHANGED onPortStatusChanged; |
| | | ONVCREVENTREPORT onSVDataReport; |
| | | ONVCREVENTREPORT onPanelDataReport; |
| | | ONPROCESSDATAREPORT onProcessDataReport; |
| | | } EquipmentListener; |
| | | |
| | | |
| | |
| | | virtual int onProcessData(CProcessData* pProcessData); |
| | | virtual int onSendAble(int port); |
| | | virtual int onReceiveAble(int port); |
| | | virtual int onProcessStateChanged(int nSlotNo, PROCESS_STATE state); |
| | | virtual int onProcessStateChanged(int nSlotNo, PROCESS_STATE prevState, PROCESS_STATE state); |
| | | virtual int getIndexerOperationModeBaseValue(); |
| | | virtual bool isSlotProcessed(int slot) { return true; }; |
| | | bool isAlarmStep(SERVO::CStep* pStep); |
| | |
| | | void printDebugString001(); |
| | | std::vector<SERVO::CSVData>& getSVDatas(); |
| | | |
| | | // 请求主配方列表 |
| | | // 请求主配方列表 |
| | | // unitNo: 0:local; Others:unit No |
| | | int masterRecipeListRequest(short unitNo, ONSYNCINGSTATECHANGED block); |
| | | |
| | | // 请求配方参数 |
| | | // masterRecipeId: 主配方id |
| | | // localRecipeId: 本地配方id |
| | | // 请求配方参数 |
| | | // masterRecipeId: 主配方id |
| | | // localRecipeId: 本地配方id |
| | | // unitNo: 0:local; Others:unit No |
| | | int recipeParameterRequest(short masterRecipeId, short localRecipeId, short unitNo, ONSYNCINGSTATECHANGED block); |
| | | |
| | | // 解析配方参数列表 |
| | | // 解析配方参数列表 |
| | | virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& params) { return 0; }; |
| | | virtual int parsingParams(const char* pszData, size_t size, std::string& strOut); |
| | | virtual int parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& params) { return 0; }; |
| | | virtual int parsingSVData(const char* pszData, size_t size, std::vector<CParam>& params) { return 0; }; |
| | | |
| | | // 获取指定的Slot |
| | | // 获取指定的Slot |
| | | CSlot* getSlot(int index); |
| | | CSlot* getSlotWithNo(int slotNo); |
| | | |
| | | // 获取一个可用的槽位 |
| | | // 获取一个可用的槽位 |
| | | CSlot* getAvailableSlot(); |
| | | |
| | | // 获取一个指定物料类型(G1,G2,G1&G2)的空槽位 |
| | | // 获取一个指定物料类型(G1,G2,G1&G2)的空槽位 |
| | | CSlot* getAvailableSlotForGlass(MaterialsType type); |
| | | CSlot* getAvailableSlotForGlassExcludeSignal(MaterialsType type); |
| | | CSlot* isSlotAvailable(unsigned int slot); |
| | | |
| | | // 在指定的槽列表中,获取一个指定物料类型(G1,G2,G1&G2)的空槽位 |
| | | // 在指定的槽列表中,获取一个指定物料类型(G1,G2,G1&G2)的空槽位 |
| | | CSlot* getAvailableSlotForGlass2(MaterialsType type, const std::vector<int>& candidates); |
| | | |
| | | // 获取一个指定物料类型(G1,G2,G1&G2)的非空槽位 |
| | | // 获取一个指定物料类型(G1,G2,G1&G2)的非空槽位 |
| | | CSlot* getNonEmptySlot(MaterialsType type); |
| | | |
| | | // 获取一个指定物料类型(G1,G2,G1&G2)的且已经加工处理的槽位 |
| | | // 获取一个指定物料类型(G1,G2,G1&G2)的且已经加工处理的槽位 |
| | | CSlot* getProcessedSlot(MaterialsType putSlotType, BOOL bJobMode = FALSE); |
| | | CSlot* getProcessedSlot2(MaterialsType putSlotType, const std::vector<int>& candidates); |
| | | CSlot* getInspFailSlot(); |
| | | CSlot* getProcessedSlotCt(unsigned int slot); |
| | | |
| | | // 获取玻璃物料 |
| | | // 获取玻璃物料 |
| | | CGlass* getGlassFromSlot(int slotNo); |
| | | CGlass* getGlassWithCassette(int cassetteSequenceNo, int jobSequenceNo); |
| | | CGlass* getAnyGlass(); |
| | |
| | | int getAllGlass(std::vector<CGlass*>& glasses); |
| | | CJobDataS* getJobDataSWithCassette(int cassetteSequenceNo, int jobSequenceNo); |
| | | |
| | | // 验证玻璃和槽是否匹配 |
| | | // 验证玻璃和槽是否匹配 |
| | | BOOL ValidateGlassSlotMatch(); |
| | | |
| | | // 是否有玻璃 |
| | | // 是否有玻璃 |
| | | BOOL hasGlass(); |
| | | BOOL slotHasGlass(int slotIndex = 0); |
| | | |
| | | // 指定槽位是否可以放置玻璃 |
| | | // 指定槽位是否可以放置玻璃 |
| | | BOOL canPlaceGlassInSlot(const short slotIndex); |
| | | |
| | | // 手动移除物料 |
| | | // 手动移除物料 |
| | | int removeGlass(int slotNo); |
| | | |
| | | // 字符串检测结果转换 |
| | | // 字符串检测结果转换 |
| | | InspResult judgeStringToInspResult(std::string& strJudge); |
| | | |
| | | // for test |
| | | void fireSetProcessState(int nSlotNo, PROCESS_STATE state) { return setProcessState(nSlotNo, state); } |
| | | |
| | | |
| | | |
| | | // 以下为从CC-Link读取到的Bit标志位检测函数 |
| | | // 以下为从CC-Link读取到的Bit标志位检测函数 |
| | | public: |
| | | BOOL isAlive(); |
| | | BOOL isCimOn(); |
| | |
| | | BOOL isLinkSignalUpstreamOn(unsigned int path, unsigned int signal); |
| | | BOOL isLinkSignalDownstreamOn(unsigned int path, unsigned int signal); |
| | | |
| | | // 只在模拟测试时使用的函数,用于模拟信号 |
| | | // 只在模拟测试时使用的函数,用于模拟信号 |
| | | void setLinkSignalUpstream(unsigned int path, unsigned int signal, BOOL bOn); |
| | | void setLinkSignalUpstreamBlock(unsigned int path, BOOL* pSignal); |
| | | void setLinkSignalDownstream(unsigned int path, unsigned int signal, BOOL bOn); |
| | |
| | | float toFloat(const char* pszAddr); |
| | | |
| | | protected: |
| | | // 部分优化/简化代码、暂实现部分,到时平铺开 |
| | | // 部分优化/简化代码、暂实现部分,到时平铺开 |
| | | void addFacDataReportStep(int dataDev, int writeSignalDev, int port); |
| | | |
| | | |
| | |
| | | std::vector<CPin*> m_outputPins; |
| | | |
| | | |
| | | // 以下为从CC-Link读取到的Bit标志位 |
| | | // 以下为从CC-Link读取到的Bit标志位 |
| | | protected: |
| | | ALIVE m_alive; |
| | | BOOL m_bCimState; // ON/OFF |
| | |
| | | unlock(); |
| | | } |
| | | }; |
| | | listener.onProcessStateChanged = [&](void* pEquipment, int slotNo, PROCESS_STATE state) -> void { |
| | | listener.onProcessStateChanged = [&](void* pEquipment, int slotNo, PROCESS_STATE prevState, PROCESS_STATE state) -> void { |
| | | ASSERT(1 <= slotNo && slotNo <= 8); |
| | | int eqid = ((CEquipment*)pEquipment)->getID(); |
| | | CGlass* pGlass = ((CEquipment*)pEquipment)->getGlassFromSlot(slotNo); |
| | |
| | | } |
| | | |
| | | if (m_listener.onProcessStateChanged != nullptr) { |
| | | m_listener.onProcessStateChanged(this, (CEquipment*)pEquipment, slotNo, state); |
| | | m_listener.onProcessStateChanged(this, (CEquipment*)pEquipment, slotNo, prevState, state); |
| | | } |
| | | }; |
| | | listener.onProcessDataReport = [&](void* pEquipment, const std::vector<CParam>& params) { |
| | | if (m_listener.onProcessDataReport != nullptr) { |
| | | m_listener.onProcessDataReport(this, (CEquipment*)pEquipment, params); |
| | | } |
| | | }; |
| | | listener.onMapMismatch = [&](void* pEquipment, short scanMap, short downMap) { |
| | |
| | | strOut.append(szBuffer); |
| | | } |
| | | LOGD("<CMaster-%s>SVDataReport:%s", ((CEquipment*)pEquipment)->getName().c_str(), strOut.c_str()); |
| | | |
| | | if (m_listener.onSVDataReport != nullptr) { |
| | | m_listener.onSVDataReport(this, (CEquipment*)pEquipment, params); |
| | | } |
| | | }; |
| | | listener.onPanelDataReport = [&](void* pEquipment, void* pContext) { |
| | | LOGD("<CMaster-%s>onPanelDataReport", ((CEquipment*)pEquipment)->getName().c_str()); |
| | |
| | | } |
| | | }; |
| | | auto fireProcessState = [&](SERVO::CEquipment* pEq, int slotNo, SERVO::PROCESS_STATE st) { |
| | | if (m_listener.onProcessStateChanged != nullptr && pEq != nullptr) { |
| | | m_listener.onProcessStateChanged(this, pEq, slotNo, st); |
| | | // Drive equipment state so listeners receive prev/current states consistently. |
| | | if (pEq != nullptr) { |
| | | pEq->fireSetProcessState(slotNo, st); |
| | | } |
| | | }; |
| | | |
| | |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, int code)> ONEQDATACHANGED; |
| | | typedef std::function<void(void* pMaster, CRobotTask* pTask, int code)> ONROBOTTASKEVENT; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, short status, __int64 data)> ONLOADPORTSTATUSCHANGED; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, int slotNo, PROCESS_STATE state)> ONPROCESSSTATECHANGED; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, int slotNo, PROCESS_STATE prevState, PROCESS_STATE state)> ONPROCESSSTATECHANGED; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, const std::vector<CParam>& params)> ONPROCESSDATAREPORTEX; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, const std::vector<CParam>& params)> ONSVDATAREPORT; |
| | | typedef std::function<void(void* pMaster, int round)> ONCTROUNDEND; |
| | | typedef std::function<void(void* pMaster, void* pj)> ONPJSTART; |
| | | typedef std::function<void(void* pMaster)> ONCONTROLJOBCHANGED; |
| | |
| | | ONROBOTTASKEVENT onRobotTaskEvent; |
| | | ONLOADPORTSTATUSCHANGED onLoadPortStatusChanged; |
| | | ONPROCESSSTATECHANGED onProcessStateChanged; |
| | | ONSVDATAREPORT onSVDataReport; |
| | | ONPROCESSDATAREPORTEX onProcessDataReport; |
| | | ONCTROUNDEND onCTRoundEnd; |
| | | ONPJSTART onCjStart; |
| | | ONPJSTART onCjEnd; |
| | |
| | | bool canCompleteControlJob(); |
| | | bool canDeleteControlJob(); |
| | | |
| | | // DAQ Bridge鐩稿叧 |
| | | // DAQ Bridge 相关 |
| | | Collector* getCollector() const { return m_pCollector; } |
| | | |
| | | private: |
| | |
| | | int m_nLastError; |
| | | std::string m_strLastError; |
| | | |
| | | // 在开始工艺前是否先需要先比较map |
| | | // 在开始工艺前是否需要先比较 map |
| | | BOOL m_isCompareMapsBeforeProceeding; |
| | | BOOL m_bJobMode; |
| | | |
| | | |
| | | // 千传圈数计数 |
| | | int m_nContinuousTransferCount; |
| | |
| | | int m_nContinuousWorkingPort; |
| | | int m_nContinuousWorkingSlot; |
| | | |
| | | // 新增已经开始处理的ProcessJob列表 |
| | | // 已经开始处理的 ProcessJob 列表 |
| | | std::vector<CProcessJob*> m_inProcesJobs; |
| | | std::vector<CProcessJob*> m_completeProcessJobs; |
| | | std::vector<CGlass*> m_queueGlasses; |
| | |
| | | return m_nValueType; |
| | | } |
| | | |
| | | int CParam::getIntValue() |
| | | int CParam::getIntValue() const |
| | | { |
| | | return m_nValue; |
| | | } |
| | |
| | | m_nValue = value; |
| | | } |
| | | |
| | | double CParam::getDoubleValue() |
| | | double CParam::getDoubleValue() const |
| | | { |
| | | if(m_nValueType == PVT_DOUBLE) |
| | | return m_fValue; |
| | |
| | | std::string& getName(); |
| | | std::string& getUnit(); |
| | | int getValueType(); |
| | | int getIntValue(); |
| | | int getIntValue() const; |
| | | void setIntValue(int value); |
| | | double getDoubleValue(); |
| | | double getDoubleValue() const; |
| | | void setDoubleValue(double value); |
| | | void Serialize(CArchive& ar); |
| | | |
| | |
| | | const char* ACK0 = &ACK[0]; |
| | | const char* ACK1 = &ACK[1]; |
| | | |
| | | // Log SECS-II message briefly to avoid huge strings causing issues. |
| | | static void LogSecsMessageBrief(const char* tag, IMessage* pMessage, size_t maxLen = 1024) |
| | | { |
| | | if (pMessage == nullptr) return; |
| | | const char* msgStr = pMessage->toString(); |
| | | if (msgStr == nullptr) return; |
| | | std::string buf(msgStr); |
| | | if (buf.size() > maxLen) { |
| | | buf = buf.substr(0, maxLen) + "...<truncated>"; |
| | | } |
| | | LOGI("%s%s", tag, buf.c_str()); |
| | | } |
| | | |
| | | unsigned __stdcall CimWorkThreadFunction(LPVOID lpParam) |
| | | { |
| | | CHsmsPassive* pPassive = (CHsmsPassive*)lpParam; |
| | |
| | | |
| | | void CHsmsPassive::setVariableValue(const char* pszName, __int64 value) |
| | | { |
| | | auto v = getVariable(pszName); |
| | | if (v != nullptr) { |
| | | // Protect variable list updates; multiple threads may set SVs. |
| | | Lock(); |
| | | if (auto v = getVariable(pszName)) { |
| | | v->setValue(value); |
| | | } |
| | | Unlock(); |
| | | } |
| | | |
| | | void CHsmsPassive::setVariableValue(const char* pszName, const char* value) |
| | | { |
| | | auto v = getVariable(pszName); |
| | | if (v != nullptr) { |
| | | Lock(); |
| | | if (auto v = getVariable(pszName)) { |
| | | v->setValue(value); |
| | | } |
| | | Unlock(); |
| | | } |
| | | |
| | | void CHsmsPassive::setVariableValue(const char* pszName, std::vector<SERVO::CVariable>& vars) |
| | | { |
| | | auto v = getVariable(pszName); |
| | | if (v != nullptr) { |
| | | Lock(); |
| | | if (auto v = getVariable(pszName)) { |
| | | v->setValue(vars); |
| | | } |
| | | Unlock(); |
| | | } |
| | | |
| | | void CHsmsPassive::withVariableLock(const std::function<void()>& fn) |
| | | { |
| | | Lock(); |
| | | if (fn) fn(); |
| | | Unlock(); |
| | | } |
| | | |
| | | static bool isValidFormat(const std::string& fmt) |
| | |
| | | HEADER* pHeader = pMessage->getHeader(); |
| | | int nStream = (pHeader->stream & 0x7F); |
| | | |
| | | LOGI("<HSMS>[Received]%s", pMessage->toString()); |
| | | LogSecsMessageBrief("<HSMS>[Received]", pMessage); |
| | | if (nStream == 1 && pHeader->function == 1) { |
| | | // S1F1 |
| | | replyAreYouThere(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 3) { |
| | | replySelectedEquipmentStatusData(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 11) { |
| | | replyStatusVariableNamelistRequest(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 23) { |
| | | replyCollectionEventNamelistRequest(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 13) { |
| | | replyEstablishCommunications(pMessage); |
| | |
| | | ASSERT(pMessage); |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]SysByte=%u sessionId:%d", pMessage->getHeader()->systemBytes, pMessage->getHeader()->sessionId); |
| | | LOGI("<HSMS>[SEND]%s", pMessage->toString()); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | |
| | | int nRet = WaitForSingleObject(pAction->getEvent(), pAction->getTimeout() * 1000); |
| | | if (nRet == WAIT_TIMEOUT) { |
| | |
| | | ASSERT(pMessage); |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]SysByte=%u sessionId:%d", pMessage->getHeader()->systemBytes, pMessage->getHeader()->sessionId); |
| | | LOGI("<HSMS>[SEND]%s", pMessage->toString()); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | |
| | | } |
| | | } |
| | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]%s", pMessage->toString()); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | } |
| | | |
| | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]%s", pMessage->toString()); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]%s", pMessage->toString()); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]%s", pMessage->toString()); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | // S1F11 |
| | | int CHsmsPassive::replyStatusVariableNamelistRequest(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | std::vector<unsigned short> reqIds; |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | if (pBody != nullptr && pBody->getType() == SITYPE::L) { |
| | | const int sz = pBody->getSubItemSize(); |
| | | for (int i = 0; i < sz; ++i) { |
| | | unsigned short id = 0; |
| | | if (pBody->getSubItemU2(i, id)) { |
| | | reqIds.push_back(id); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Build response list items: {L:3 SVID, SVNAME, UNITS} |
| | | std::vector<unsigned short> svids; |
| | | std::set<unsigned short> requested(reqIds.begin(), reqIds.end()); |
| | | Lock(); |
| | | if (reqIds.empty()) { |
| | | for (auto v : m_variabels) { |
| | | svids.push_back(static_cast<unsigned short>(v->getVarialbleId())); |
| | | } |
| | | } |
| | | else { |
| | | // include requested IDs (existing + unknown marker) |
| | | for (auto id : requested) { |
| | | svids.push_back(id); |
| | | } |
| | | } |
| | | Unlock(); |
| | | |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 12, pRecv->getHeader()->systemBytes); |
| | | ASSERT(pMessage); |
| | | |
| | | ISECS2Item* pList = pMessage->getBody(); // Body is L[n] of {SVID, SVNAME, UNITS} |
| | | for (auto id : svids) { |
| | | ISECS2Item* pEntry = pList->addItem(); |
| | | pEntry->addU2Item(id, "SVID"); |
| | | SERVO::CVariable* v = getVariable((int)id); |
| | | if (v != nullptr) { |
| | | pEntry->addItem(v->getName().c_str(), "SVNAME"); |
| | | // Use remark as UNITS if provided; empty string if none. |
| | | pEntry->addItem(v->getRemark().c_str(), "UNITS"); |
| | | } |
| | | else { |
| | | // Unknown SVID: A:0 for name/units |
| | | pEntry->addItem("", "SVNAME"); |
| | | pEntry->addItem("", "UNITS"); |
| | | } |
| | | } |
| | | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return ER_NOERROR; |
| | | } |
| | | |
| | | // S1F23 |
| | | int CHsmsPassive::replyCollectionEventNamelistRequest(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | std::vector<unsigned short> reqIds; |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | if (pBody != nullptr && pBody->getType() == SITYPE::L) { |
| | | const int sz = pBody->getSubItemSize(); |
| | | for (int i = 0; i < sz; ++i) { |
| | | unsigned short id = 0; |
| | | if (pBody->getSubItemU2(i, id)) { |
| | | reqIds.push_back(id); |
| | | } |
| | | } |
| | | } |
| | | |
| | | struct CEInfo { |
| | | unsigned short id{ 0 }; |
| | | std::string name; |
| | | std::vector<unsigned short> vids; |
| | | }; |
| | | std::vector<CEInfo> ceInfos; |
| | | { |
| | | Lock(); |
| | | if (reqIds.empty()) { |
| | | for (auto e : m_collectionEvents) { |
| | | if (e == nullptr) continue; |
| | | CEInfo info; |
| | | info.id = static_cast<unsigned short>(e->getEventId()); |
| | | info.name = e->getName(); |
| | | std::set<unsigned short> vidSet; |
| | | for (auto rpt : e->getReports()) { |
| | | if (rpt == nullptr) continue; |
| | | for (auto vid : rpt->getVids()) { |
| | | vidSet.insert(static_cast<unsigned short>(vid)); |
| | | } |
| | | } |
| | | info.vids.assign(vidSet.begin(), vidSet.end()); |
| | | ceInfos.push_back(std::move(info)); |
| | | } |
| | | } |
| | | else { |
| | | for (auto id : reqIds) { |
| | | CEInfo info; |
| | | info.id = id; |
| | | SERVO::CCollectionEvent* e = getEvent(id); |
| | | if (e != nullptr) { |
| | | info.name = e->getName(); |
| | | std::set<unsigned short> vidSet; |
| | | for (auto rpt : e->getReports()) { |
| | | if (rpt == nullptr) continue; |
| | | for (auto vid : rpt->getVids()) { |
| | | vidSet.insert(static_cast<unsigned short>(vid)); |
| | | } |
| | | } |
| | | info.vids.assign(vidSet.begin(), vidSet.end()); |
| | | } |
| | | ceInfos.push_back(std::move(info)); |
| | | } |
| | | } |
| | | Unlock(); |
| | | } |
| | | |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 24, pRecv->getHeader()->systemBytes); |
| | | ASSERT(pMessage); |
| | | |
| | | ISECS2Item* pList = pMessage->getBody(); // Body is L[n] of {CEID, CENAME, L[VIDs]} |
| | | for (const auto& info : ceInfos) { |
| | | ISECS2Item* pEntry = pList->addItem(); |
| | | pEntry->addU2Item(info.id, "CEID"); |
| | | pEntry->addItem(info.name.c_str(), "CENAME"); // empty if unknown |
| | | ISECS2Item* pVidList = pEntry->addItem(); |
| | | for (auto vid : info.vids) { |
| | | pVidList->addU2Item(vid, "VID"); |
| | | } |
| | | } |
| | | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return ER_NOERROR; |
| | | } |
| | | |
| | | // S2F13 |
| | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]%s", pMessage->toString()); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]%s", pMessage->toString()); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]%s", pMessage->toString()); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | |
| | | m_pPassive->sendMessage(pReply); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pReply->getHeader()->sessionId, pReply->getHeader()->sType, pReply->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]%s", pReply->toString()); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pReply); |
| | | HSMS_Destroy1Message(pReply); |
| | | |
| | | |
| | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]%s", pMessage->toString()); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]%s", pMessage->toString()); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | |
| | |
| | | void setVariableValue(const char* pszName, __int64 value); |
| | | void setVariableValue(const char* pszName, const char* value); |
| | | void setVariableValue(const char* pszName, std::vector<SERVO::CVariable>& vars); |
| | | // 执行一段持锁的代码块,用于保证 set+send 的原子性 |
| | | void withVariableLock(const std::function<void()>& fn); |
| | | |
| | | // 从文件中加载CReport列表 |
| | | int loadReports(const char* pszFilepath); |
| | |
| | | int replyAreYouThere(IMessage* pRecv); |
| | | int replyEstablishCommunications(IMessage* pRecv); |
| | | int replySelectedEquipmentStatusData(IMessage* pRecv); |
| | | int replyStatusVariableNamelistRequest(IMessage* pRecv); // S1F11/S1F12 |
| | | int replyCollectionEventNamelistRequest(IMessage* pRecv); // S1F23/S1F24 |
| | | int replyOnLine(IMessage* pRecv); |
| | | int replyOffLine(IMessage* pRecv); |
| | | int replyEquipmentConstantRequest(IMessage* pRecv); |
| | |
| | | #include "TransferManager.h" |
| | | #include "RecipeManager.h" |
| | | #include "GlassLogDb.h" |
| | | #include "CParam.h" |
| | | #include <algorithm> |
| | | #include <iomanip> |
| | | #include <sstream> |
| | | #include <array> |
| | | #include <map> |
| | | |
| | | |
| | |
| | | { |
| | | const auto prev = m_currentControlState; |
| | | if (newState != m_currentControlState) { |
| | | m_hsmsPassive.setVariableValue("PreviousControlState", (__int64)static_cast<uint8_t>(prev)); |
| | | m_currentControlState = newState; |
| | | } |
| | | |
| | | // Always keep SV in sync (even if state didn't change or variables were just loaded). |
| | | m_hsmsPassive.setVariableValue("CurrentControlState", (__int64)static_cast<uint8_t>(m_currentControlState)); |
| | | |
| | | if (newState != prev) { |
| | | // S6F11 (CEID=600): ControlStateChanged |
| | | m_hsmsPassive.requestEventReportSend("ControlStateChanged"); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PreviousControlState", (__int64)static_cast<uint8_t>(prev)); |
| | | m_hsmsPassive.setVariableValue("CurrentControlState", (__int64)static_cast<uint8_t>(m_currentControlState)); |
| | | m_hsmsPassive.requestEventReportSend("ControlStateChanged"); |
| | | }); |
| | | notifyInt(RX_CODE_CONTROL_STATE_CHANGED, static_cast<int>(m_currentControlState)); |
| | | } else { |
| | | // Keep SV in sync even if unchanged/load-time refresh. |
| | | m_hsmsPassive.setVariableValue("CurrentControlState", (__int64)static_cast<uint8_t>(m_currentControlState)); |
| | | } |
| | | } |
| | | |
| | |
| | | return CAACK_5; |
| | | } |
| | | |
| | | m_hsmsPassive.setVariableValue("SlotMapScan", pLoadPort->getScanCassetteMap()); |
| | | m_hsmsPassive.setVariableValue("SlotMapDownload", pLoadPort->getDownloadCassetteMap()); |
| | | m_hsmsPassive.requestEventReportSend_SlotMapVerificationOK(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("SlotMapScan", pLoadPort->getScanCassetteMap()); |
| | | m_hsmsPassive.setVariableValue("SlotMapDownload", pLoadPort->getDownloadCassetteMap()); |
| | | m_hsmsPassive.requestEventReportSend_SlotMapVerificationOK(); |
| | | }); |
| | | |
| | | // Host 确认 SlotMap 后再开始加工/流程 |
| | | m_master.proceedWithCarrier(portIndex); |
| | |
| | | vars.push_back(var); |
| | | } |
| | | |
| | | m_hsmsPassive.setVariableValue("PJQueued", vars); |
| | | m_hsmsPassive.requestEventReportSend_PJ_Queued(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PJQueued", vars); |
| | | m_hsmsPassive.requestEventReportSend_PJ_Queued(); |
| | | }); |
| | | return nRet; |
| | | }; |
| | | listener.onControlJobCreate = [&](void* pFrom, SERVO::CControlJob& controlJob) -> int { |
| | |
| | | |
| | | |
| | | SERVO::MasterListener masterListener; |
| | | auto formatParamValue = [](const CParam& p) { |
| | | std::ostringstream oss; |
| | | oss.setf(std::ios::fixed); |
| | | oss << std::setprecision(4) << p.getDoubleValue(); |
| | | return oss.str(); |
| | | }; |
| | | masterListener.onMasterStateChanged = [&](void* pMaster, SERVO::MASTERSTATE state) -> void { |
| | | LOGI("<CModel>Master state changed(%d)", (int)state); |
| | | notify(RX_CODE_MASTER_STATE_CHANGED); |
| | |
| | | masterListener.onEqVcrEventReport = [&](void* pMaster, SERVO::CEquipment* pEquipment, SERVO::CVcrEventReport* pReport) { |
| | | LOGE("<CModel>onEqVcrEventReport."); |
| | | if (pReport != nullptr) { |
| | | m_hsmsPassive.setVariableValue("VCRPanelID", pReport->getGlassId().c_str()); |
| | | int nRet = m_hsmsPassive.requestEventReportSend_OCR_PanelID_Read_OK(); |
| | | if (nRet != ER_NOERROR) { |
| | | LOGE("<CModel>requestEventReportSend_OCR_PanelID_Read_OK failed, ret=%d", nRet); |
| | | } |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("VCRPanelID", pReport->getGlassId().c_str()); |
| | | int nRet = m_hsmsPassive.requestEventReportSend_OCR_PanelID_Read_OK(); |
| | | if (nRet != ER_NOERROR) { |
| | | LOGE("<CModel>requestEventReportSend_OCR_PanelID_Read_OK failed, ret=%d", nRet); |
| | | } |
| | | }); |
| | | } |
| | | }; |
| | | masterListener.onEqDataChanged = [&](void* pMaster, SERVO::CEquipment* pEquipment, int code) { |
| | |
| | | const int eqId = (pEquipment != nullptr) ? pEquipment->getID() : 0; |
| | | const short prevStatus = s_prevPortStatus[eqId]; |
| | | s_prevPortStatus[eqId] = status; |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | |
| | | // Unified PortStateChange event + SV maintenance |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PortTransferState", (__int64)status); // maintain SVID=100 |
| | | m_hsmsPassive.setVariableValue("PortStateChangePortId", pLoadPort->getID()); |
| | | m_hsmsPassive.setVariableValue("PortState", (__int64)status); |
| | | m_hsmsPassive.requestEventReportSend("PortStateChange"); |
| | | }); |
| | | } |
| | | |
| | | if (status == PORT_INUSE) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("CarrierID", pLoadPort->getCassetteId().c_str()); |
| | | if (prevStatus != PORT_INUSE && pLoadPort->isCompareMapsBeforeProceeding()) { |
| | | // TODO(Host协商): |
| | | // 文档中标明:1-Empty,3-Exist,因此我们可能需要将uint的map转换为list上传 |
| | | m_hsmsPassive.setVariableValue("SlotMap", pLoadPort->getScanCassetteMap()); |
| | | m_hsmsPassive.requestEventReportSend_CheckSlotMap(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("CarrierID", pLoadPort->getCassetteId().c_str()); |
| | | if (prevStatus != PORT_INUSE && pLoadPort->isCompareMapsBeforeProceeding()) { |
| | | // TODO(Host协商): |
| | | // 文档中标明:1-Empty,3-Exist,因此我们可能需要将uint的map转换为list上传 |
| | | m_hsmsPassive.setVariableValue("SlotMap", pLoadPort->getScanCassetteMap()); |
| | | m_hsmsPassive.requestEventReportSend_CheckSlotMap(); |
| | | } |
| | | } |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_CarrierID_Readed(); |
| | | m_hsmsPassive.requestEventReportSend_CarrierID_Readed(); |
| | | }); |
| | | } |
| | | else if (status == PORT_BLOCKED) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("BlockedPortId", pLoadPort->getID()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_Port_Blocked(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("BlockedPortId", pLoadPort->getID()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_Port_Blocked(); |
| | | }); |
| | | } |
| | | else if (status == PORT_LOAD_READY) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("LoadReadyPortId", pLoadPort->getID()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_Port_Load_Ready(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("LoadReadyPortId", pLoadPort->getID()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_Port_Load_Ready(); |
| | | }); |
| | | } |
| | | else if (status == PORT_UNLOAD_READY) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("UnloadReadyPortId", pLoadPort->getID()); |
| | | if (prevStatus == PORT_INUSE) { |
| | | m_hsmsPassive.setVariableValue("ReadyToReleasePortId", pLoadPort->getID()); |
| | | m_hsmsPassive.requestEventReportSend_Port_Ready_To_Release(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("UnloadReadyPortId", pLoadPort->getID()); |
| | | if (prevStatus == PORT_INUSE) { |
| | | m_hsmsPassive.setVariableValue("ReadyToReleasePortId", pLoadPort->getID()); |
| | | m_hsmsPassive.requestEventReportSend_Port_Ready_To_Release(); |
| | | } |
| | | } |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_Port_Unload_Ready(); |
| | | m_hsmsPassive.requestEventReportSend_Port_Unload_Ready(); |
| | | }); |
| | | } |
| | | else if (status == PORT_EMPTY) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("LoadPortNotAssocPortId", pLoadPort->getID()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_LoadPortNotAssoc(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("LoadPortNotAssocPortId", pLoadPort->getID()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_LoadPortNotAssoc(); |
| | | }); |
| | | } |
| | | notifyPtr(RX_CODE_LOADPORT_STATUS_CHANGED, pEquipment); |
| | | }; |
| | | masterListener.onProcessStateChanged = [&](void* pMaster, SERVO::CEquipment* pEquipment, int slotNo, SERVO::PROCESS_STATE state) { |
| | | // SubEqpStart/SubEqpEnd: align to log's EV_SubEqpStart/EV_SubEqpEnd stage (no report payload required). |
| | | masterListener.onProcessStateChanged = [&](void* pMaster, SERVO::CEquipment* pEquipment, int slotNo, SERVO::PROCESS_STATE prevState, SERVO::PROCESS_STATE state) { |
| | | (void)pMaster; |
| | | if (pEquipment != nullptr) { |
| | | m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str()); |
| | | const int eqId = pEquipment ? pEquipment->getID() : 0; |
| | | |
| | | // 保持同一锁范围内:更新所需 SV 并依次上报,保证 set+send 原子性 |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | // Timestamp VID (Clock, VID=500) for all related reports. |
| | | m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str()); |
| | | |
| | | // Common payload VIDs for SubEqp/Unit |
| | | if (pEquipment != nullptr) { |
| | | m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str()); |
| | | } |
| | | m_hsmsPassive.setVariableValue("SubEqpSlot", slotNo); |
| | | |
| | | // ProcessStateChanged (equipment-level): update SVs 700/701, then report CEID=700 |
| | | m_hsmsPassive.setVariableValue("PreviousProcessState", (__int64)prevState); |
| | | m_hsmsPassive.setVariableValue("CurrentProcessState", (__int64)state); |
| | | m_hsmsPassive.requestEventReportSend("ProcessStateChanged"); |
| | | |
| | | // SubEqp events (per equipment, ignore slot distinction except payload) |
| | | static std::map<int, SERVO::PROCESS_STATE> s_prevSubEqpState; |
| | | const auto prevEqState = s_prevSubEqpState[eqId]; |
| | | if (prevEqState != state) { |
| | | // state change |
| | | m_hsmsPassive.requestEventReportSend("SubEqpStateChange"); |
| | | } |
| | | if (state == SERVO::PROCESS_STATE::Processing) { |
| | | m_hsmsPassive.requestEventReportSend_SubEqpStart(); |
| | | } |
| | | else if (state == SERVO::PROCESS_STATE::Complete) { |
| | | m_hsmsPassive.requestEventReportSend_SubEqpEnd(); |
| | | } |
| | | s_prevSubEqpState[eqId] = state; |
| | | |
| | | // Unit events (per equipment slot) |
| | | static std::map<int, std::map<int, SERVO::PROCESS_STATE>> s_prevUnitState; |
| | | const auto prevUnitState = s_prevUnitState[eqId][slotNo]; |
| | | if (prevUnitState != state) { |
| | | m_hsmsPassive.requestEventReportSend("UnitStateChange"); |
| | | if (state == SERVO::PROCESS_STATE::Processing) { |
| | | m_hsmsPassive.requestEventReportSend("UnitStart"); |
| | | } |
| | | else if (state == SERVO::PROCESS_STATE::Complete) { |
| | | m_hsmsPassive.requestEventReportSend("UnitEnd"); |
| | | } |
| | | s_prevUnitState[eqId][slotNo] = state; |
| | | } |
| | | }); |
| | | }; |
| | | masterListener.onSVDataReport = [&](void* pMaster, SERVO::CEquipment* pEquipment, const std::vector<CParam>& params) { |
| | | (void)pMaster; |
| | | const int eqId = pEquipment ? pEquipment->getID() : 0; |
| | | |
| | | auto sendSv = [&](const auto& vidMap, const char* evName) { |
| | | const size_t count = (std::min)(params.size(), vidMap.size()); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str()); |
| | | for (size_t idx = 0; idx < count; ++idx) { |
| | | const std::string val = formatParamValue(params[idx]); |
| | | m_hsmsPassive.setVariableValue(std::to_string(vidMap[idx]).c_str(), val.c_str()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend(evName); |
| | | }); |
| | | }; |
| | | |
| | | if (eqId == EQ_ID_Bonder1 || eqId == EQ_ID_Bonder2) { |
| | | static constexpr std::array<int, 19> vids = { |
| | | 6000,6001,6002,6003,6004,6005,6006,6007,6008,6009, |
| | | 6010,6011,6012,6013,6014,6015,6016,6017,6018 |
| | | }; |
| | | sendSv(vids, "BonderSVData"); |
| | | } |
| | | m_hsmsPassive.setVariableValue("SubEqpSlot", slotNo); |
| | | if (state == SERVO::PROCESS_STATE::Processing) { |
| | | m_hsmsPassive.requestEventReportSend_SubEqpStart(); |
| | | else if (eqId == EQ_ID_VACUUMBAKE) { |
| | | static constexpr std::array<int, 18> vids = { |
| | | 6200,6201,6202,6203,6204,6205,6206,6207,6208, |
| | | 6209,6210,6211,6212,6213,6214,6215,6216,6217 |
| | | }; |
| | | sendSv(vids, "VacuumBakeSVData"); |
| | | } |
| | | else if (state == SERVO::PROCESS_STATE::Complete) { |
| | | m_hsmsPassive.requestEventReportSend_SubEqpEnd(); |
| | | else if (eqId == EQ_ID_BAKE_COOLING) { |
| | | static constexpr std::array<int, 20> vids = { |
| | | 6400,6401,6402,6403,6404,6405,6406,6407,6408,6409, |
| | | 6410,6411,6412,6413,6414,6415,6416,6417,6418,6419 |
| | | }; |
| | | sendSv(vids, "BakeCoolingSVData"); |
| | | } |
| | | else if (eqId == EQ_ID_MEASUREMENT) { |
| | | static constexpr std::array<int, 2> vids = { 6600, 6601 }; |
| | | sendSv(vids, "MeasurementSVData"); |
| | | } |
| | | }; |
| | | masterListener.onProcessDataReport = [&](void* pMaster, SERVO::CEquipment* pEquipment, const std::vector<CParam>& params) { |
| | | (void)pMaster; |
| | | const int eqId = pEquipment ? pEquipment->getID() : 0; |
| | | |
| | | auto sendProcess = [&](const auto& vidMap, const char* evName) { |
| | | const size_t count = (std::min)(params.size(), vidMap.size()); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str()); |
| | | for (size_t idx = 0; idx < count; ++idx) { |
| | | const std::string val = formatParamValue(params[idx]); |
| | | m_hsmsPassive.setVariableValue(std::to_string(vidMap[idx]).c_str(), val.c_str()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend(evName); |
| | | }); |
| | | }; |
| | | |
| | | if (eqId == EQ_ID_Bonder1 || eqId == EQ_ID_Bonder2) { |
| | | static constexpr std::array<int, 22> vids = { |
| | | 6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110, |
| | | 6111,6112,6113,6114,6115,6116,6117,6118,6119,6120,6121 |
| | | }; |
| | | sendProcess(vids, "BonderProcessData"); |
| | | } |
| | | else if (eqId == EQ_ID_VACUUMBAKE) { |
| | | static constexpr std::array<int, 5> vids = { 6300,6301,6302,6303,6304 }; |
| | | sendProcess(vids, "VacuumBakeProcessData"); |
| | | } |
| | | else if (eqId == EQ_ID_BAKE_COOLING) { |
| | | static constexpr std::array<int, 4> vids = { 6500,6501,6502,6503 }; |
| | | sendProcess(vids, "BakeCoolingProcessData"); |
| | | } |
| | | else if (eqId == EQ_ID_MEASUREMENT) { |
| | | static constexpr std::array<int, 4> vids = { 6700,6701,6702,6703 }; |
| | | sendProcess(vids, "MeasurementProcessData"); |
| | | } |
| | | }; |
| | | masterListener.onCTRoundEnd = [&](void* pMaster, int round) { |
| | | m_configuration.setContinuousTransferCount(round); |
| | | }; |
| | | masterListener.onCjStart = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.setVariableValue("CJStartID", ((SERVO::CControlJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_CJ_Start(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("CJStartID", ((SERVO::CControlJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_CJ_Start(); |
| | | }); |
| | | }; |
| | | masterListener.onCjEnd = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.setVariableValue("CJEndID", ((SERVO::CControlJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_CJ_End(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("CJEndID", ((SERVO::CControlJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_CJ_End(); |
| | | }); |
| | | |
| | | // 结批,保存ControlJob |
| | | // |
| | | }; |
| | | masterListener.onPjStart = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.setVariableValue("PJStartID", ((SERVO::CProcessJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_PJ_Start(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PJStartID", ((SERVO::CProcessJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_PJ_Start(); |
| | | }); |
| | | }; |
| | | masterListener.onPjEnd = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.setVariableValue("PJEndID", ((SERVO::CProcessJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_PJ_End(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PJEndID", ((SERVO::CProcessJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_PJ_End(); |
| | | }); |
| | | }; |
| | | masterListener.onPanelStart = [&](void* pMaster, void* pPanel) { |
| | | m_hsmsPassive.setVariableValue("PanelStartID", ((SERVO::CGlass*)pPanel)->getID().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_Panel_Start(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PanelStartID", ((SERVO::CGlass*)pPanel)->getID().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_Panel_Start(); |
| | | }); |
| | | }; |
| | | masterListener.onPanelEnd = [&](void* pMaster, void* pPanel) { |
| | | m_hsmsPassive.setVariableValue("PanelEndID", ((SERVO::CGlass*)pPanel)->getID().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_Panel_End(); |
| | | // Placeholder payload to match log shape: EV_PROCESS_DATA_REPORT can carry a single A-string (may be empty). |
| | | m_hsmsPassive.setVariableValue("ProcessDataReportText", ""); |
| | | m_hsmsPassive.requestEventReportSend_ProcessDataReport(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PanelEndID", ((SERVO::CGlass*)pPanel)->getID().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_Panel_End(); |
| | | // Placeholder payload to match log shape: EV_PROCESS_DATA_REPORT can carry a single A-string (may be empty). |
| | | m_hsmsPassive.setVariableValue("ProcessDataReportText", ""); |
| | | m_hsmsPassive.requestEventReportSend_ProcessDataReport(); |
| | | }); |
| | | auto& db = GlassLogDb::Instance(); |
| | | db.insertFromCGlass((*(SERVO::CGlass*)pPanel)); |
| | | SERVO::CGlass* pBuddy = ((SERVO::CGlass*)pPanel)->getBuddy(); |
| | |
| | | 10018,ProcessDataReport,,(33) |
| | | 10015,SubEqpStart,,(10015) |
| | | 10016,SubEqpEnd,,(10016) |
| | | 10017,SubEqpStateChange,,(10017) |
| | | 10000,RecipeChanged,,(10000) |
| | | 10030,CarrierArrived,,(10300) |
| | | 10031,CarrierRemoved,,(10300) |
| | |
| | | 50010,Port_Blocked,,(50010) |
| | | 50011,OCR_PanelID_Read_OK,扫码事件上报,(50012) |
| | | 50012,Port_Ready_To_Release,,(50013) |
| | | 50020,PortStateChange,,(50020) |
| | | 60000,BonderSVData,,(60000) |
| | | 61000,BonderProcessData,,(61000) |
| | | 62000,VacuumBakeSVData,,(62000) |
| | | 63000,VacuumBakeProcessData,,(63000) |
| | | 64000,BakeCoolingSVData,,(64000) |
| | | 65000,BakeCoolingProcessData,,(65000) |
| | | 66000,MeasurementSVData,,(66000) |
| | | 67000,MeasurementProcessData,,(67000) |
| | | 12000,UnitStart,,(12000) |
| | | 12001,UnitStateChange,,(12001) |
| | | 12002,UnitEnd,,(12002) |
| | |
| | | 50012,(5014) |
| | | 50013,(5015) |
| | | 50014,(5016) |
| | | 50020,(500,5020,5021) |
| | | 60000,(500,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016,6017,6018) |
| | | 61000,(500,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116,6117,6118,6119,6120,6121) |
| | | 62000,(500,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,6211,6212,6213,6214,6215,6216,6217) |
| | | 63000,(500,6300,6301,6302,6303,6304) |
| | | 64000,(500,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6414,6415,6416,6417,6418,6419) |
| | | 65000,(500,6500,6501,6502,6503) |
| | | 66000,(500,6600,6601) |
| | | 67000,(500,6700,6701,6702,6703) |
| | | 10015,(5018,5019) |
| | | 10016,(5018,5019) |
| | | 10017,(500,5018) |
| | | 12000,(500,5018,5019) |
| | | 12001,(500,5018,5019) |
| | | 12002,(500,5018,5019) |
| | |
| | | 5017,ProcessDataReportText,A50,EV_PROCESS_DATA_REPORT payload string (placeholder) |
| | | 5018,SubEqpName,A20,Equipment name for EV_SubEqpStart/EV_SubEqpEnd |
| | | 5019,SubEqpSlot,U1,Slot number for EV_SubEqpStart/EV_SubEqpEnd |
| | | 5020,PortStateChangePortId,U1,"Port ID for PortStateChange" |
| | | 5021,PortState,U1,"Port transfer/state code for PortStateChange" |
| | | 6000,Bonder_SV_ProcessStep,A20,Bonder SV |
| | | 6001,Bonder_SV_BladderPressure,A20,Bonder SV |
| | | 6002,Bonder_SV_UpperChamberPressure,A20,Bonder SV |
| | | 6003,Bonder_SV_PipeVacuumGauge,A20,Bonder SV |
| | | 6004,Bonder_SV_ChamberVacuumGauge,A20,Bonder SV |
| | | 6005,Bonder_SV_UpperTemp1,A20,Bonder SV |
| | | 6006,Bonder_SV_UpperTemp2,A20,Bonder SV |
| | | 6007,Bonder_SV_UpperTemp3,A20,Bonder SV |
| | | 6008,Bonder_SV_UpperTemp4,A20,Bonder SV |
| | | 6009,Bonder_SV_UpperTemp5,A20,Bonder SV |
| | | 6010,Bonder_SV_UpperTemp6,A20,Bonder SV |
| | | 6011,Bonder_SV_LowerTemp1,A20,Bonder SV |
| | | 6012,Bonder_SV_LowerTemp2,A20,Bonder SV |
| | | 6013,Bonder_SV_LowerTemp3,A20,Bonder SV |
| | | 6014,Bonder_SV_LowerTemp4,A20,Bonder SV |
| | | 6015,Bonder_SV_LowerTemp5,A20,Bonder SV |
| | | 6016,Bonder_SV_LowerTemp6,A20,Bonder SV |
| | | 6017,Bonder_SV_HeatingRemaining,A20,Bonder SV |
| | | 6018,Bonder_SV_PressingRemaining,A20,Bonder SV |
| | | 6100,Bonder_PD_AlignDelay,A20,Bonder ProcessData |
| | | 6101,Bonder_PD_DwellTime,A20,Bonder ProcessData |
| | | 6102,Bonder_PD_BreakVacuumDelay,A20,Bonder ProcessData |
| | | 6103,Bonder_PD_TurboPumpStartDelay,A20,Bonder ProcessData |
| | | 6104,Bonder_PD_AttachVacuumDelay,A20,Bonder ProcessData |
| | | 6105,Bonder_PD_HeatingWaitDelay,A20,Bonder ProcessData |
| | | 6106,Bonder_PD_BladderPressureSet,A20,Bonder ProcessData |
| | | 6107,Bonder_PD_BladderPressurizeRate,A20,Bonder ProcessData |
| | | 6108,Bonder_PD_BladderDepressurizeRate,A20,Bonder ProcessData |
| | | 6109,Bonder_PD_AttachPressureLimit,A20,Bonder ProcessData |
| | | 6110,Bonder_PD_UpperZTorqueSpeed,A20,Bonder ProcessData |
| | | 6111,Bonder_PD_UpperTempSet,A20,Bonder ProcessData |
| | | 6112,Bonder_PD_LowerTempSet,A20,Bonder ProcessData |
| | | 6113,Bonder_PD_PreAttachSpeed,A20,Bonder ProcessData |
| | | 6114,Bonder_PD_AttachSpeed,A20,Bonder ProcessData |
| | | 6115,Bonder_PD_UpperHeatDistance,A20,Bonder ProcessData |
| | | 6116,Bonder_PD_AttachPressIn,A20,Bonder ProcessData |
| | | 6117,Bonder_PD_UpperBreakVacuumDist,A20,Bonder ProcessData |
| | | 6118,Bonder_PD_LowerPinBreakVacuumDist,A20,Bonder ProcessData |
| | | 6119,Bonder_PD_LowerPinHeatDistance,A20,Bonder ProcessData |
| | | 6120,Bonder_PD_PumpGaugeSet,A20,Bonder ProcessData |
| | | 6121,Bonder_PD_TurboReachSet,A20,Bonder ProcessData |
| | | 6200,VacuumBake_SV_A_ProcessStep,A20,VacuumBake SV |
| | | 6201,VacuumBake_SV_A_ChamberVacuum,A20,VacuumBake SV |
| | | 6202,VacuumBake_SV_A_Temp1,A20,VacuumBake SV |
| | | 6203,VacuumBake_SV_A_Temp2,A20,VacuumBake SV |
| | | 6204,VacuumBake_SV_A_Temp4,A20,VacuumBake SV |
| | | 6205,VacuumBake_SV_A_Temp5,A20,VacuumBake SV |
| | | 6206,VacuumBake_SV_A_Temp6,A20,VacuumBake SV |
| | | 6207,VacuumBake_SV_A_Temp7,A20,VacuumBake SV |
| | | 6208,VacuumBake_SV_A_BakeRemaining,A20,VacuumBake SV |
| | | 6209,VacuumBake_SV_B_ProcessStep,A20,VacuumBake SV |
| | | 6210,VacuumBake_SV_B_ChamberVacuum,A20,VacuumBake SV |
| | | 6211,VacuumBake_SV_B_Temp1,A20,VacuumBake SV |
| | | 6212,VacuumBake_SV_B_Temp2,A20,VacuumBake SV |
| | | 6213,VacuumBake_SV_B_Temp4,A20,VacuumBake SV |
| | | 6214,VacuumBake_SV_B_Temp5,A20,VacuumBake SV |
| | | 6215,VacuumBake_SV_B_Temp6,A20,VacuumBake SV |
| | | 6216,VacuumBake_SV_B_Temp7,A20,VacuumBake SV |
| | | 6217,VacuumBake_SV_B_BakeRemaining,A20,VacuumBake SV |
| | | 6300,VacuumBake_PD_ParamIndex,A20,VacuumBake ProcessData |
| | | 6301,VacuumBake_PD_HeatTime,A20,VacuumBake ProcessData |
| | | 6302,VacuumBake_PD_BreakVacuumTime,A20,VacuumBake ProcessData |
| | | 6303,VacuumBake_PD_VacuumReach,A20,VacuumBake ProcessData |
| | | 6304,VacuumBake_PD_TempSet,A20,VacuumBake ProcessData |
| | | 6400,BakeCooling_SV_A_BakeStep,A20,BakeCooling SV |
| | | 6401,BakeCooling_SV_A_Temp1,A20,BakeCooling SV |
| | | 6402,BakeCooling_SV_A_Temp2,A20,BakeCooling SV |
| | | 6403,BakeCooling_SV_A_Temp4,A20,BakeCooling SV |
| | | 6404,BakeCooling_SV_A_Temp5,A20,BakeCooling SV |
| | | 6405,BakeCooling_SV_A_Temp6,A20,BakeCooling SV |
| | | 6406,BakeCooling_SV_A_Temp7,A20,BakeCooling SV |
| | | 6407,BakeCooling_SV_A_BakeRemaining,A20,BakeCooling SV |
| | | 6408,BakeCooling_SV_A_CoolStep,A20,BakeCooling SV |
| | | 6409,BakeCooling_SV_A_CoolRemaining,A20,BakeCooling SV |
| | | 6410,BakeCooling_SV_B_BakeStep,A20,BakeCooling SV |
| | | 6411,BakeCooling_SV_B_Temp1,A20,BakeCooling SV |
| | | 6412,BakeCooling_SV_B_Temp2,A20,BakeCooling SV |
| | | 6413,BakeCooling_SV_B_Temp4,A20,BakeCooling SV |
| | | 6414,BakeCooling_SV_B_Temp5,A20,BakeCooling SV |
| | | 6415,BakeCooling_SV_B_Temp6,A20,BakeCooling SV |
| | | 6416,BakeCooling_SV_B_Temp7,A20,BakeCooling SV |
| | | 6417,BakeCooling_SV_B_BakeRemaining,A20,BakeCooling SV |
| | | 6418,BakeCooling_SV_B_CoolStep,A20,BakeCooling SV |
| | | 6419,BakeCooling_SV_B_CoolRemaining,A20,BakeCooling SV |
| | | 6500,BakeCooling_PD_ParamIndex,A20,BakeCooling ProcessData |
| | | 6501,BakeCooling_PD_TimeOrTemp1,A20,BakeCooling ProcessData |
| | | 6502,BakeCooling_PD_TimeOrTemp2,A20,BakeCooling ProcessData |
| | | 6503,BakeCooling_PD_Reserved,A20,BakeCooling ProcessData |
| | | 6600,Measurement_SV_ProcessStep,A20,Measurement SV |
| | | 6601,Measurement_SV_AOIScore,A20,Measurement SV |
| | | 6700,Measurement_PD_ParamIndex,A20,Measurement ProcessData |
| | | 6701,Measurement_PD_Time,A20,Measurement ProcessData |
| | | 6702,Measurement_PD_Value1,A20,Measurement ProcessData |
| | | 6703,Measurement_PD_Value2,A20,Measurement ProcessData |
| | | 10200,SlotMap,U2,SlotMap(Scan) |
| | | 10201,SlotMapScan,U2,SlotMap(Scan) |
| | | 10202,SlotMapDownload,U2,SlotMap(Download) |