| | |
| | | #include "RecipeManager.h" |
| | | #include "GlassLogDb.h" |
| | | #include "CParam.h" |
| | | #include "CJobDataS.h" |
| | | #include <algorithm> |
| | | #include <iomanip> |
| | | #include <sstream> |
| | | #include <array> |
| | | #include <map> |
| | | |
| | | |
| | |
| | | m_master.enableEventReport(bEnable); |
| | | } |
| | | }; |
| | | listener.onDeletePPID = [&](void* pFrom, const std::vector<std::string>& ppids) -> bool { |
| | | (void)pFrom; |
| | | bool allOk = true; |
| | | std::vector<std::string> targets = ppids; |
| | | if (targets.empty()) { |
| | | // L:0 => delete all PPIDs |
| | | targets = RecipeManager::getInstance().getAllPPID(); |
| | | } |
| | | for (auto& ppid : targets) { |
| | | bool ok = RecipeManager::getInstance().deleteRecipeByPPID(ppid); |
| | | allOk = allOk && ok; |
| | | LOGI("<CModel>DeletePPID: %s, result=%s", ppid.c_str(), ok ? "OK" : "FAIL"); |
| | | } |
| | | return allOk; |
| | | }; |
| | | listener.onEnableDisableAlarmReport = [&](void* pFrom, bool bEnable, unsigned int id) -> void { |
| | | LOGI("onEnableDisableAlarmReport bEnable:%s, id:%d", bEnable ? _T("YES") : _T("NO"), id); |
| | | if (id == 0) { |
| | |
| | | |
| | | |
| | | 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); |
| | |
| | | notifyPtrAndInt(RX_CODE_EQ_ROBOT_TASK, pTask, nullptr, code); |
| | | |
| | | }; |
| | | masterListener.onJobReceived = [&](void* pMaster, SERVO::CEquipment* pEquipment, int port, SERVO::CJobDataS* pJobDataS) { |
| | | (void)pMaster; |
| | | (void)port; |
| | | if (pEquipment == nullptr || pJobDataS == nullptr) return; |
| | | const int eqId = pEquipment->getID(); |
| | | const int recipeId = pJobDataS->getMasterRecipe(); |
| | | std::string recipe = RecipeManager::getInstance().getPPIDById(recipeId); |
| | | if (recipe.empty()) { |
| | | recipe = std::to_string(recipeId); |
| | | } |
| | | const std::string prev = pEquipment->getCurrentRecipe(); |
| | | if (recipe.empty() || recipe == prev) { |
| | | pEquipment->setCurrentRecipe(recipe); |
| | | return; |
| | | } |
| | | pEquipment->setCurrentRecipe(recipe); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str()); |
| | | m_hsmsPassive.setVariableValue("EQPPExecName", recipe.c_str()); |
| | | m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str()); |
| | | const char* recipeVid = nullptr; |
| | | switch (eqId) { |
| | | case EQ_ID_Bonder1: recipeVid = "Bonder1CurrentRecipe"; break; |
| | | case EQ_ID_Bonder2: recipeVid = "Bonder2CurrentRecipe"; break; |
| | | case EQ_ID_VACUUMBAKE: recipeVid = "VacuumBakeCurrentRecipe"; break; |
| | | case EQ_ID_BAKE_COOLING: recipeVid = "BakeCoolingCurrentRecipe"; break; |
| | | case EQ_ID_MEASUREMENT: recipeVid = "MeasurementCurrentRecipe"; break; |
| | | case EQ_ID_EFEM: recipeVid = "EFEMCurrentRecipe"; break; |
| | | default: break; |
| | | } |
| | | if (recipeVid != nullptr) { |
| | | m_hsmsPassive.setVariableValue(recipeVid, recipe.c_str()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend("RecipeChanged"); |
| | | }); |
| | | }; |
| | | masterListener.onLoadPortStatusChanged = [&] (void* pMaster, SERVO::CEquipment* pEquipment, short status, __int64 data) { |
| | | LOGE("<CModel>onLoadPortStatusChanged. status = %d", status); |
| | | static std::map<int, short> s_prevPortStatus; |
| | |
| | | } |
| | | }); |
| | | }; |
| | | 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"); |
| | | } |
| | | 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 (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; |
| | | if (eqId != EQ_ID_Bonder1 && eqId != EQ_ID_Bonder2) return; |
| | | |
| | | auto formatVal = [](const CParam& p) { |
| | | std::ostringstream oss; |
| | | oss.setf(std::ios::fixed); |
| | | oss << std::setprecision(4) << p.getDoubleValue(); |
| | | return oss.str(); |
| | | 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); |
| | | }); |
| | | }; |
| | | |
| | | static const int vidMap[] = { |
| | | 6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110, |
| | | 6111,6112,6113,6114,6115,6116,6117,6118,6119,6120,6121 |
| | | }; |
| | | const size_t count = (std::min)(params.size(), sizeof(vidMap) / sizeof(vidMap[0])); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str()); |
| | | for (size_t idx = 0; idx < count; ++idx) { |
| | | auto& p = params[idx]; |
| | | std::string val = formatVal(p); |
| | | m_hsmsPassive.setVariableValue(std::to_string(vidMap[idx]).c_str(), val.c_str()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend("BonderProcessData"); |
| | | }); |
| | | 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); |