#include "stdafx.h" #include "CEquipment.h" #include "ToolUnits.h" namespace SERVO { CEquipment::CEquipment() : m_nID(0), m_strName(""), m_strDescription(""), m_station(0, 255) { m_listener = { nullptr, nullptr }; m_alive = {FALSE, 0, FALSE}; m_bCimState = FALSE; m_bUpstreamInline = FALSE; m_bDownstreamInline = FALSE; m_bLocalAlarm = FALSE; m_bAutoRecipeChange = FALSE; m_bVCREnable[0] = FALSE; m_pCclink = nullptr; m_nBaseAlarmId = 0; InitializeCriticalSection(&m_criticalSection); } CEquipment::~CEquipment() { for (auto item : m_glassList) { item->release(); } m_glassList.clear(); for (auto item : m_mapStep) { delete item.second; } m_mapStep.clear(); for (auto item : m_inputPins) { delete item; } m_inputPins.clear(); for (auto item : m_outputPins) { delete item; } m_outputPins.clear(); DeleteCriticalSection(&m_criticalSection); } void CEquipment::setListener(EquipmentListener listener) { m_listener.onAlive = listener.onAlive; m_listener.onCimStateChanged = listener.onCimStateChanged; } void CEquipment::setCcLink(CCCLinkIEControl* pCcLink) { m_pCclink = pCcLink; } void CEquipment::setBaseAlarmId(int nBaseId) { m_nBaseAlarmId = nBaseId; } int CEquipment::getBaseAlarmId() { return m_nBaseAlarmId; } void CEquipment::getProperties(std::vector>& 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")); } std::map& CEquipment::getSteps() { return m_mapStep; } CStep* CEquipment::getStep(unsigned int addr) { auto iter = m_mapStep.find(addr); if (iter == m_mapStep.end()) return nullptr; return iter->second; } CStep* CEquipment::getStepWithName(const char* pszName) { for (auto item : m_mapStep) { if (item.second->getName().compare(pszName) == 0) { return item.second; } } return nullptr; } int CEquipment::addStep(unsigned int addr, CStep* pStep) { auto iter = m_mapStep.find(addr); if (iter != m_mapStep.end()) return -1; pStep->setEquipment(this); pStep->setCcLink(m_pCclink); m_mapStep[addr] = pStep; return 0; } void CEquipment::init() { initPins(); for (auto item : m_mapStep) { item.second->init(); } } void CEquipment::term() { for (auto item : m_mapStep) { item.second->term(); } } void CEquipment::setID(int nID) { m_nID = nID; } int CEquipment::getID() { return m_nID; } void CEquipment::setName(const char* pszName) { m_strName = pszName; } std::string& CEquipment::getName() { return m_strName; } void CEquipment::setDescription(const char* pszDescription) { m_strDescription = pszDescription; } std::string& CEquipment::getDescription() { return m_strDescription; } void CEquipment::setStation(int network, int station) { m_station.nNetNo = network; m_station.nStNo = station; } const StationIdentifier& CEquipment::getStation() { return m_station; } void CEquipment::getAttributeVector(CAttributeVector& attrubutes) { attrubutes.clear(); attrubutes.addAttribute(new CAttribute("Network", std::to_string(m_station.nNetNo).c_str(), "")); attrubutes.addAttribute(new CAttribute("Station", std::to_string(m_station.nStNo).c_str(), "")); attrubutes.addAttribute(new CAttribute("ID", std::to_string(m_nID).c_str(), "")); attrubutes.addAttribute(new CAttribute("Name", m_strName.c_str(), "")); attrubutes.addAttribute(new CAttribute("Description", m_strDescription.c_str(), "")); attrubutes.addAttribute(new CAttribute("Alive", this->isAlive() ? _T("TRUE") : _T("FALSE"), "")); attrubutes.addAttribute(new CAttribute("CIM State", m_bCimState ? _T("ON") : _T("OFF"), "")); attrubutes.addAttribute(new CAttribute("Upstream", m_bUpstreamInline ? _T("Inline") : _T("Offline"), "")); attrubutes.addAttribute(new CAttribute("Downstream", m_bDownstreamInline ? _T("Inline") : _T("Offline"), "")); attrubutes.addAttribute(new CAttribute("Local Alarm", m_bLocalAlarm ? _T("TRUE") : _T("FALSE"), "")); attrubutes.addAttribute(new CAttribute("Auto Recipe Change", m_bAutoRecipeChange ? _T("TRUE") : _T("FALSE"), "")); char szTemp[256]; for (int i = 0; i < VCR_MAX; i++) { sprintf_s(szTemp, 256, "VCR-%d", i + 1); attrubutes.addAttribute(new CAttribute(szTemp, m_bVCREnable[i] ? _T("Enable") : _T("Disable"), "")); } for (auto item : m_inputPins) { attrubutes.addAttribute(new CAttribute(item->getName().c_str(), std::to_string((int)item->getType()).c_str(), "")); } for (auto item : m_outputPins) { attrubutes.addAttribute(new CAttribute(item->getName().c_str(), std::to_string((int)item->getType()).c_str(), "")); } for (auto item : m_glassList) { attrubutes.addAttribute(new CAttribute("Glass", item->getID().c_str(), "")); } } void CEquipment::setReadBitBlock(unsigned int start, unsigned int end) { m_blockReadBit.type = (unsigned int)DeviceType::B; m_blockReadBit.start = start; m_blockReadBit.end = end; m_blockReadBit.size = (m_blockReadBit.end - m_blockReadBit.start + 1) / 8; ASSERT(m_blockReadBit.size < BLOCK_BUFFER_MAX); } MemoryBlock& CEquipment::getReadBitBlock() { return m_blockReadBit; } void CEquipment::setWriteBitBlock(unsigned int start, unsigned int end) { m_blockWriteBit.type = (unsigned int)DeviceType::LB; m_blockWriteBit.start = start; m_blockWriteBit.end = end; m_blockWriteBit.size = (m_blockWriteBit.end - m_blockWriteBit.start + 1) / 8; } MemoryBlock& CEquipment::getWriteBitBlock() { return m_blockWriteBit; } void CEquipment::onTimer(UINT nTimerid) { // ÿ¸ôÒ»Ã룬¼ì²éÒ»ÏÂALIVE״̬ static int tick = 0; tick++; if (tick % (4 * 1) == 0) { m_alive.count++; if (m_alive.alive && m_alive.count > ALIVE_TIMEOUT) { m_alive.alive = FALSE; if (m_listener.onAlive != nullptr) { m_listener.onAlive(this, m_alive.alive); } } } } void CEquipment::serialize(CArchive& ar) { if (ar.IsStoring()) { Lock(); int count = (int)m_glassList.size(); ar << count; for (auto item : m_glassList) { item->serialize(ar); } Unlock(); } else { Lock(); int count; ar >> count; for (int i = 0; i < count; i++) { CGlass* pGlass = new CGlass(); pGlass->serialize(ar); addGlassToList(pGlass); } Unlock(); } } void CEquipment::onReceiveLBData(const char* pszData, size_t size) { /* TRACE("%s onReceiveLBData: %d bytes\n", m_strName.c_str(), size); for (unsigned int i = 0; i < size; i++) { if (pszData[i] != 0) TRACE("%d[%x]\n", i, pszData[i]); } */ // ÒÔϽâÊͺʹ¦ÀíÊý¾Ý BOOL bFlag; int index = 0x340; // alive bFlag = isBitOn(pszData, size, index); if (!equalBool(m_alive.flag, bFlag)) { m_alive.flag = bFlag; m_alive.count = 0; // ״̬ if (!m_alive.alive) { m_alive.alive = TRUE; if (m_listener.onAlive != nullptr) { m_listener.onAlive(this, m_alive.alive); } } } // CIM State bFlag = isBitOn(pszData, size, ++index); if (!equalBool(m_bCimState, bFlag)) { m_bCimState = bFlag; if (m_listener.onCimStateChanged != nullptr) { m_listener.onCimStateChanged(this, m_bCimState); } } // UpstreamInline bFlag = isBitOn(pszData, size, ++index); if (!equalBool(m_bUpstreamInline, bFlag)) { m_bUpstreamInline = bFlag; } // DownstreamInline bFlag = isBitOn(pszData, size, ++index); if (!equalBool(m_bDownstreamInline, bFlag)) { m_bDownstreamInline = bFlag; } // LocalAlarm bFlag = isBitOn(pszData, size, ++index); if (!equalBool(m_bLocalAlarm, bFlag)) { m_bLocalAlarm = bFlag; } // AutoRecipeChange bFlag = isBitOn(pszData, size, ++index); if (!equalBool(m_bAutoRecipeChange, bFlag)) { m_bAutoRecipeChange = bFlag; } // AutoRecipeChange bFlag = isBitOn(pszData, size, ++index); if (!equalBool(m_bVCREnable[0], bFlag)) { m_bVCREnable[0] = bFlag; } // ÒÔϸù¾ÝÐźÅ×öÁ÷³Ì´¦Àí CStep* pStep; // Equipment Mode Change Report(0x360) // Equipment Status Change Report(0x361) // Equipment Alarm Change Report(0x362 ~ 0x366) for (int i = 0; i < 7; i++) { index = 0x360 + i;; bFlag = isBitOn(pszData, size, index); pStep = getStep(index); if (pStep != nullptr) { ((CReadStep*)pStep)->onReadSignal(bFlag); } } index = 0x350; bFlag = isBitOn(pszData, size, index); pStep = getStep(index); if (pStep != nullptr) { ((CWriteStep*)pStep)->onRecvSignal(bFlag); } } BOOL CEquipment::isBitOn(const char* pszData, size_t size, int index) { int byteIndex, bitIndex; byteIndex = (index) / 8; bitIndex = (index) % 8; return CToolUnits::getBit(pszData[byteIndex], bitIndex); } BOOL CEquipment::equalBool(BOOL b1, BOOL b2) { return (b1 && b2) || (!b1 && !b2); } BOOL CEquipment::isAlive() { return m_alive.alive; } BOOL CEquipment::isCimOn() { return m_bCimState; } BOOL CEquipment::isUpstreamInline() { return m_bUpstreamInline; } BOOL CEquipment::isDownstreamInline() { return m_bDownstreamInline; } BOOL CEquipment::isLocalAlarm() { return m_bLocalAlarm; } BOOL CEquipment::isAutoRecipeChange() { return m_bAutoRecipeChange; } BOOL CEquipment::isVCREnable(unsigned int index) { if (index >= VCR_MAX) return FALSE; return m_bVCREnable[index]; } CPin* CEquipment::addPin(PinType type, char* pszName) { // ²»ÔÊÐíÃû×ÖÌí¼ÓÖØ¸´µÄpin CPin* pPin = getPin(pszName); if (pPin != nullptr) return nullptr; // Ìí¼Óµ½PinÁÐ±í£¬¿´ÊÇÊäÈëpin»òÊä³öpin if (type == PinType::INPUT) { pPin = new CPin(this, type, pszName); m_inputPins.push_back(pPin); return pPin; } else if (type == PinType::OUTPUT) { pPin = new CPin(this, type, pszName); m_outputPins.push_back(pPin); return pPin; } return nullptr; } CPin* CEquipment::getPin(char* pszName) { for (auto item : m_inputPins) { if (item->getName().compare(pszName) == 0) { return item; } } for (auto item : m_outputPins) { if (item->getName().compare(pszName) == 0) { return item; } } return nullptr; } std::vector& CEquipment::getInputPins() { return m_inputPins; } std::vector& CEquipment::getOutputPins() { return m_outputPins; } int CEquipment::recvIntent(CPin* pPin, CIntent* pIntent) { ASSERT(pPin); CPin* pFromPin = pPin->getConnectedPin(); ASSERT(pFromPin); CEquipment* pFromEq = pFromPin->getEquipment(); ASSERT(pFromEq); LOGI("<%s-%s>ÊÕµ½À´×Ô<%s.%s>µÄIntent<%d,%s,0x%x>", this->getName().c_str(), pPin->getName().c_str(), pFromEq->getName().c_str(), pFromPin->getName().c_str(), pIntent->getCode(), pIntent->getMsg(), pIntent->getContext()); // ÒÔϽâÊÍ´¦ÀíÊý¾Ý int code = pIntent->getCode(); // ²âÊÔ if (code == FLOW_TEST) { AfxMessageBox(pIntent->getMsg()); return FLOW_ACCEPT; } // ÐźŠif (code == FLOW_SIGNAL) { return FLOW_ACCEPT; } // Êý¾Ý if (code == FLOW_SIGNAL) { return FLOW_ACCEPT; } // ÎïÁÏ if (code == FLOW_MOVE_MATERIAL) { CGlass* pGlass = (CGlass*)pIntent->getContext(); ASSERT(pGlass); if (!glassWillArrive(pGlass)) { return FLOW_REJECT; } return glassArrived(pGlass); } return FLOW_ACCEPT; } int CEquipment::outputGlass(int port) { CPin* pOutPin = nullptr; if (port == 0) { pOutPin = getPin("Out"); if (pOutPin == nullptr) { pOutPin = getPin("Out1"); } } else if (port == 1) { pOutPin = getPin("Out2"); } if (pOutPin == nullptr) { return -1; } // Ä£ÄâÈ¡³öµÚÒ»ÕÅPanel,´«Ë͵½ÏÂÒ»»·½Ú Lock(); if (m_glassList.empty()) { Unlock(); return -2; } CGlass* pContext = m_glassList.front(); pContext->addRef(); CIntent intent(FLOW_MOVE_MATERIAL, "", pContext); int nRet = pOutPin->sendIntent(&intent); if (nRet == FLOW_REJECT) { LOGE("¶Ô·½¾Ü¾ø½ÓÊÕIntent."); } else if (nRet == FLOW_ACCEPT) { m_glassList.pop_front(); pContext->release(); // Ìí¼Óµ½ÁжÓʱaddRef, È¡³öʱrelease } pContext->release(); Unlock(); return 0; } BOOL CEquipment::glassWillArrive(CGlass* pGlass) { return TRUE; } int CEquipment::glassArrived(CGlass* pGlass) { Lock(); pGlass->addRef(); m_glassList.push_back(pGlass); Unlock(); return FLOW_ACCEPT; } void CEquipment::addGlassToList(CGlass* pGlass) { ASSERT(pGlass); Lock(); pGlass->addRef(); m_glassList.push_back(pGlass); Unlock(); } }