| | |
| | | #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> params(tempParams.begin(), tempParams.begin() + min(n, (int)tempParams.size())); |
| | | pGlass->addParams(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) { |
| | |
| | | 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; |
| | | } |
| | |
| | | #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; |
| | | |
| | |
| | | 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.onMapMismatch = [&](void* pEquipment, short scanMap, short downMap) { |
| | |
| | | } |
| | | }; |
| | | 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, int round)> ONCTROUNDEND; |
| | | typedef std::function<void(void* pMaster, void* pj)> ONPJSTART; |
| | | typedef std::function<void(void* pMaster)> ONCONTROLJOBCHANGED; |
| | |
| | | |
| | | 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) |
| | |
| | | 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); |
| | |
| | | { |
| | | 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.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.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.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PJQueued", vars); |
| | | m_hsmsPassive.requestEventReportSend_PJ_Queued(); |
| | | }); |
| | | return nRet; |
| | | }; |
| | | listener.onControlJobCreate = [&](void* pFrom, SERVO::CControlJob& controlJob) -> int { |
| | |
| | | masterListener.onEqVcrEventReport = [&](void* pMaster, SERVO::CEquipment* pEquipment, SERVO::CVcrEventReport* pReport) { |
| | | LOGE("<CModel>onEqVcrEventReport."); |
| | | if (pReport != nullptr) { |
| | | 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) { |
| | |
| | | s_prevPortStatus[eqId] = status; |
| | | if (status == PORT_INUSE) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("CarrierID", pLoadPort->getCassetteId().c_str()); |
| | | if (prevStatus != PORT_INUSE && pLoadPort->isCompareMapsBeforeProceeding()) { |
| | |
| | | } |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_CarrierID_Readed(); |
| | | }); |
| | | } |
| | | else if (status == PORT_BLOCKED) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | 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); |
| | | 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); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("UnloadReadyPortId", pLoadPort->getID()); |
| | | if (prevStatus == PORT_INUSE) { |
| | |
| | | } |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_Port_Unload_Ready(); |
| | | }); |
| | | } |
| | | else if (status == PORT_EMPTY) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | 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; |
| | | 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.onCTRoundEnd = [&](void* pMaster, int round) { |
| | | m_configuration.setContinuousTransferCount(round); |
| | | }; |
| | | masterListener.onCjStart = [&](void* pMaster, void* pj) { |
| | | 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.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.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PJStartID", ((SERVO::CProcessJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_PJ_Start(); |
| | | }); |
| | | }; |
| | | masterListener.onPjEnd = [&](void* pMaster, void* pj) { |
| | | 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.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PanelStartID", ((SERVO::CGlass*)pPanel)->getID().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_Panel_Start(); |
| | | }); |
| | | }; |
| | | masterListener.onPanelEnd = [&](void* pMaster, void* pPanel) { |
| | | 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) |
| | | 12000,UnitStart,,(12000) |
| | | 12001,UnitStateChange,,(12001) |
| | | 12002,UnitEnd,,(12002) |
| | |
| | | 50014,(5016) |
| | | 10015,(5018,5019) |
| | | 10016,(5018,5019) |
| | | 10017,(500,5018) |
| | | 12000,(500,5018,5019) |
| | | 12001,(500,5018,5019) |
| | | 12002,(500,5018,5019) |