chenluhua1980
2025-11-18 3cb4638bcb93a8fdf4cfea140025bbc299d35d47
SourceCode/Bond/Servo/HsmsPassive.cpp
@@ -103,6 +103,43 @@
}
void CHsmsPassive::addVariableValueToItem(ISECS2Item* pParent, SERVO::CVariable* pVariable)
{
   ASSERT(pParent);
   ASSERT(pVariable);
   ISECS2Item* pItemList;
   SERVO::SVFromat format = pVariable->getFormat();
   switch (format)
   {
   case SERVO::SVFromat::U1:
      pParent->addU1Item((unsigned char)pVariable->getIntValue(), "SV");
      break;
   case SERVO::SVFromat::U2:
      pParent->addU2Item((unsigned char)pVariable->getIntValue(), "SV");
      break;
   case SERVO::SVFromat::I2:
      pParent->addI2Item((unsigned char)pVariable->getIntValue(), "SV");
      break;
   case SERVO::SVFromat::A20:
   case SERVO::SVFromat::A50:
      pParent->addItem(pVariable->getValue().c_str(), "SV");
      break;
   case SERVO::SVFromat::L:
      pItemList = pParent->addItem();
      {
         auto vars = pVariable->getVarsValue();
         for (auto v : vars) {
            addVariableValueToItem(pItemList, &v);
         }
      }
      break;
   default:
      break;
   }
}
void CHsmsPassive::linkEventReport(unsigned int CEID, unsigned int RPTID)
{
   SERVO::CCollectionEvent* pEvent = getEvent(CEID);
@@ -288,6 +325,14 @@
   auto v = getVariable(pszName);
   if (v != nullptr) {
      v->setValue(value);
   }
}
void CHsmsPassive::setVariableValue(const char* pszName, std::vector<SERVO::CVariable>& vars)
{
   auto v = getVariable(pszName);
   if (v != nullptr) {
      v->setValue(vars);
   }
}
@@ -536,6 +581,9 @@
         // S1F1
         replyAreYouThere(pMessage);
      }
      else if (nStream == 1 && pHeader->function == 3) {
         replySelectedEquipmentStatusData(pMessage);
      }
      else if (nStream == 1 && pHeader->function == 13) {
         replyEstablishCommunications(pMessage);
      }
@@ -583,6 +631,12 @@
      }
      else if (nStream == 10 && pHeader->function == 3) {
         replyTerminalDisplay(pMessage);
      }
      else if (nStream == 14 && pHeader->function == 9) {
         replyCreateObj(pMessage);
      }
      else if (nStream == 16 && pHeader->function == 15) {
         replyPRJobMultiCreate(pMessage);
      }
   };
@@ -898,6 +952,46 @@
   m_pPassive->sendMessage(pMessage);
   LOGI("<HSMS>[SECS Msg SEND]%s", pMessage->toString());
   HSMS_Destroy1Message(pMessage);
   return 0;
}
// S1F3
int CHsmsPassive::replySelectedEquipmentStatusData(IMessage* pRecv)
{
   if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
      return ER_NOTSELECT;
   }
   IMessage* pMessage = NULL;
   HSMS_Create1Message(pMessage, m_nSessionId, 1, 4, pRecv->getHeader()->systemBytes);
   ASSERT(pMessage);
   unsigned char SVU1 = 0;
   unsigned int SVID = 0;
   ISECS2Item* pBody = pRecv->getBody();
   if (pBody == nullptr || pBody->getType() != SITYPE::L) {
      pMessage->getBody()->addU1Item(SVU1, "SV");
      goto MYREPLY;
   }
   if (!pBody->getSubItemU4(0, SVID)) {
      pMessage->getBody()->addU1Item(SVU1, "SV");
      goto MYREPLY;
   }
   SERVO::CVariable* pVariable = getVariable(SVID);
   if (pVariable == nullptr) {
      pMessage->getBody()->addU1Item(SVU1, "SV");
      goto MYREPLY;
   }
   addVariableValueToItem(pMessage->getBody(), pVariable);
MYREPLY:
   m_pPassive->sendMessage(pMessage);
   LOGI("<HSMS>[SECS Msg SEND]%s", pMessage->toString());
   HSMS_Destroy1Message(pMessage);
   return 0;
}
@@ -1447,6 +1541,245 @@
   return 0;
}
// S14F9
int CHsmsPassive::replyCreateObj(IMessage* pRecv)
{
   if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
      return ER_NOTSELECT;
   }
   ISECS2Item* pBody = pRecv->getBody();
   if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR;
   // 是否创建成功并准备回复报文
   bool bCreateOk = false;
   IMessage* pReply = NULL;
   HSMS_Create1Message(pReply, m_nSessionId, 14, 10, ++m_nSystemByte);
   ASSERT(pReply);
   // 解释数据,得到ControlJob
   ISECS2Item* pItemAttrs, * pItemAttr, *pItemAttrData;
   const char* pszObjSpec, *pszObjType, *pszAttrId, *pszProcessJobId;
   std::string strObjName, strObjId;
   if (!pBody->getSubItemString(0, pszObjSpec)) return ER_PARAM_ERROR;
   if (!pBody->getSubItemString(1, pszObjType)) return ER_PARAM_ERROR;
   pReply->getBody()->addItem(pszObjSpec, "OBJSPEC");
   ISECS2Item* pReplyItemAttrs = pReply->getBody()->addItem();
   ISECS2Item* pReplyItemAcks = pReply->getBody()->addItem();
   ISECS2Item* pReplyItemAck = pReplyItemAcks->addU1Item(0, "OBJACK");
   ISECS2Item* pReplyItemErrs = pReplyItemAcks->addItem();
   // 当前只处理类各为ControlJob
   if (_strcmpi(pszObjType, "ControlJob") == 0) {
      // 类id
      std::regex re("^([^:]+):([^>]+)>");
      std::smatch match;
      std::string strObjSpec(pszObjSpec);
      if (!std::regex_search(strObjSpec, match, re)) {
         ISECS2Item* pItemError = pReplyItemErrs->addItem();
         pItemError->addU4Item(2001, "ERRCODE");
         pItemError->addItem("参数或报文不正确", "ERRTEXT");
         goto MYREPLY;
      }
      if (match[1].compare("ControlJob") != 0) {
         ISECS2Item* pItemError = pReplyItemErrs->addItem();
         pItemError->addU4Item(2001, "ERRCODE");
         pItemError->addItem("不支持的OBJ", "ERRTEXT");
         goto MYREPLY;
      }
      strObjId = match[2];
      // 创建类CControlJob
      SERVO::CControlJob controlJob(strObjId);
      // 类属性
      pItemAttrs = pBody->getSubItem(2);
      if (pItemAttrs == nullptr) return ER_PARAM_ERROR;
      for (int i = 0; i < pItemAttrs->getSubItemSize(); i++) {
         pItemAttr = pItemAttrs->getSubItem(i);
         if (pItemAttr == nullptr) continue;
         if (!pItemAttr->getSubItemString(0, pszAttrId)) continue;
         if (_strcmpi(pszAttrId, CJ_ATTR_PRIORITY) == 0) {
            uint8_t priority;
            if (pItemAttr->getSubItemU1(1, priority)) {
               controlJob.setPriority(priority);
            }
         }
         else if (_strcmpi(pszAttrId, CJ_ATTR_PRJOBLIST) == 0) {
            pItemAttrData = pItemAttr->getSubItem(1);
            if (pItemAttrData != nullptr && pItemAttrData->getType() == SITYPE::L) {
               for (int i = 0; i < pItemAttrData->getSubItemSize(); i++) {
                  if (pItemAttrData->getSubItemString(i, pszProcessJobId)) {
                     std::string strProcessJobId(pszProcessJobId);
                     controlJob.addPJ(strProcessJobId);
                  }
               }
            }
         }
      }
      ASSERT(m_listener.onControlJobCreate != nullptr);
      int nRet = m_listener.onControlJobCreate(this, controlJob);
      bCreateOk = nRet == 0;
      // 添加新建类的各种属性到回复报文中
      if(bCreateOk) {
         {
            ISECS2Item* pReplyItemAttr = pReplyItemAttrs->addItem();
            pReplyItemAttr->addItem(CJ_ATTR_PRIORITY, "ATTRID");
            pReplyItemAttr->addU1Item(controlJob.priority(), "ATTRDATA");
         }
         {
            ISECS2Item* pReplyItemAttr = pReplyItemAttrs->addItem();
            pReplyItemAttr->addItem(CJ_ATTR_PRJOBLIST, "ATTRID");
            ISECS2Item* pItemPjs = pReplyItemAttr->addItem();
            auto pjIds = controlJob.pjIds();
            for (auto id : pjIds) {
               pItemPjs->addItem(id.c_str(), "PRJOBID");
            }
         }
      }
      else {
         auto issues = controlJob.issues();
         for (auto i : issues) {
            ISECS2Item* pItemError = pReplyItemErrs->addItem();
            pItemError->addU4Item(i.code, "ERRCODE");
            pItemError->addItem(i.text.c_str(), "ERRTEXT");
         }
      }
   }
   else {
      ISECS2Item* pItemError = pReplyItemErrs->addItem();
      pItemError->addU4Item(2001, "ERRCODE");
      pItemError->addItem("不支持的OBJ", "ERRTEXT");
   }
   // 完善报文并回复
MYREPLY:
   pReplyItemAck->setU1(bCreateOk ? 0 : 1, "OBJACK");
   m_pPassive->sendMessage(pReply);
   LOGI("<HSMS>[SECS Msg SEND]S14F10 (SysByte=%u)", pReply->getHeader()->systemBytes);
   HSMS_Destroy1Message(pReply);
   return 0;
}
// S16F15
int CHsmsPassive::replyPRJobMultiCreate(IMessage* pRecv)
{
   if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
      return ER_NOTSELECT;
   }
   ISECS2Item* pBody = pRecv->getBody();
   if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR;
   // 解释数据,得到CProcessJob
   ISECS2Item* pItemPjs, * pItemPj,* pItemCarriers, * pItemCarrier, *pItemSlots, *pItemRecipes;
   unsigned int DATAID;
   const char* pszPrjobid, *pszMF, *pszCarrierId, *pszRecipeName;
   std::string strCarrierId;
   unsigned int len;
   unsigned char slot, PRRECIPEMETHOD;
   std::vector<unsigned char> slots;
   std::vector<SERVO::CProcessJob*> pjs;
   if (!pBody->getSubItemU4(0, DATAID)) return ER_PARAM_ERROR;
   pItemPjs = pBody->getSubItem(1);
   if (pItemPjs == nullptr) return ER_PARAM_ERROR;
   for (int i = 0; i < pItemPjs->getSubItemSize(); i++) {
      pItemPj = pItemPjs->getSubItem(i);
      if (pItemPj == nullptr) continue;
      if (!pItemPj->getSubItemString(0, pszPrjobid)) continue;
      if (!pItemPj->getSubItemBinary(1, pszMF, len)) continue;
      pItemCarriers = pItemPj->getSubItem(2);
      if (pItemCarriers == nullptr) continue;
      pItemRecipes = pItemPj->getSubItem(3);
      if (pItemRecipes == nullptr) continue;
      SERVO::CProcessJob* pj = new SERVO::CProcessJob(pszPrjobid);
      int size = pItemCarriers->getSubItemSize();
      for (int j = 0; j < size; j++) {
         pItemCarrier = pItemCarriers->getSubItem(j);
         strCarrierId.clear();
         if (pItemCarrier->getSubItemString(0, pszCarrierId)) {
            strCarrierId = pszCarrierId;
         }
         slots.clear();
         pItemSlots = pItemCarrier->getSubItem(1);
         if (pItemSlots != nullptr) {
            int size2 = pItemSlots->getSubItemSize();
            for (int k = 0; k < size2; k++) {
               if (pItemSlots->getSubItemU1(k, slot)) {
                  slots.push_back(slot);
               }
            }
         }
         pj->addCarrier(strCarrierId, slots);
      }
      if (pItemRecipes->getSubItemU1(0, PRRECIPEMETHOD)
         && pItemRecipes->getSubItemString(1, pszRecipeName)) {
         pj->setRecipe(SERVO::RecipeMethod(PRRECIPEMETHOD), std::string(pszRecipeName));
      }
      pjs.push_back(pj);
   }
   ASSERT(m_listener.onPRJobMultiCreate != nullptr);
   int nRet = m_listener.onPRJobMultiCreate(this, pjs);
   // 回复报文
   IMessage* pMessage = NULL;
   HSMS_Create1Message(pMessage, m_nSessionId, 16, 16, ++m_nSystemByte);
   ASSERT(pMessage);
   ISECS2Item* pItemPrjobIds = pMessage->getBody()->addItem();
   ISECS2Item* pItemErrors = pMessage->getBody()->addItem();
   bool bHasError = false;
   for (auto p : pjs) {
      if (p->issues().empty()) {
         pItemPrjobIds->addItem(p->id().c_str(), "PRJOBID");
      }
      else {
         bHasError = true;
      }
   }
   if (bHasError) {
      pItemErrors->addBoolItem(false, "ACKA");
      ISECS2Item* pItemErrors2 = pItemErrors->addItem();
      for (auto p : pjs) {
         if (!p->issues().empty()) {
            ISECS2Item* pItemErr = pItemErrors2->addItem();
            pItemErr->addU4Item(p->issues()[0].code, "ERRCODE");
            pItemErr->addItem(("<" + p->id() + ">" + p->issues()[0].text).c_str(), "ERRTEXT");
         }
      }
   }
   m_pPassive->sendMessage(pMessage);
   LOGI("<HSMS>[SECS Msg SEND]S16F16 (SysByte=%u)", pMessage->getHeader()->systemBytes);
   HSMS_Destroy1Message(pMessage);
   // 释放有问题(未添加到master)的内存
   for (auto p : pjs) {
      if(!p->issues().empty()) delete p;
   }
   pjs.clear();
   return 0;
}
// S5F1
int CHsmsPassive::requestAlarmReport(int ALCD, int ALID, const char* ALTX)
{
@@ -1504,9 +1837,9 @@
   pItemList2->addU4Item(pReport->getReportId(), "RPTID");
   ISECS2Item* pItemList3 = pItemList2->addItem();
   auto values = pReport->getVariables();
   for (auto item : values) {
      pItemList3->addItem(item->getValue().c_str(), "V");
   auto vars = pReport->getVariables();
   for (auto var : vars) {
      addVariableValueToItem(pItemList3, var);
   }
   pAction->setSendMessage(pMessage);
   if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) {
@@ -1541,6 +1874,55 @@
   return requestEventReportSend("CarrierID_Readed");
}
int CHsmsPassive::requestEventReportSend_Port_Unload_Ready()
{
   return requestEventReportSend("Port_Unload_Ready");
}
int CHsmsPassive::requestEventReportSend_Port_Load_Ready()
{
   return requestEventReportSend("Port_Load_Ready");
}
int CHsmsPassive::requestEventReportSend_Port_Blocked()
{
   return requestEventReportSend("Port_Blocked");
}
int CHsmsPassive::requestEventReportSend_PJ_Queued()
{
   return requestEventReportSend("PJ_Queued");
}
int CHsmsPassive::requestEventReportSend_PJ_Start()
{
   return requestEventReportSend("PJ_Start");
}
int CHsmsPassive::requestEventReportSend_PJ_End()
{
   return requestEventReportSend("PJ_End");
}
int CHsmsPassive::requestEventReportSend_CJ_Start()
{
   return requestEventReportSend("CJ_Start");
}
int CHsmsPassive::requestEventReportSend_CJ_End()
{
   return requestEventReportSend("CJ_End");
}
int CHsmsPassive::requestEventReportSend_Panel_Start()
{
   return requestEventReportSend("Panel_Start");
}
int CHsmsPassive::requestEventReportSend_Panel_End()
{
   return requestEventReportSend("Panel_End");
}