| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "CLoadPort.h" |
| | | #include "CGlassPool.h" |
| | | #include "Servo.h" |
| | |
| | | m_bAutoChangeEnable = FALSE; |
| | | m_nNextCassetteSequenceNo = 0; |
| | | m_isCompareMapsBeforeProceeding = FALSE; |
| | | m_downloadCassetteMap = 0; |
| | | } |
| | | |
| | | CLoadPort::~CLoadPort() |
| | |
| | | CEquipment::term(); |
| | | } |
| | | |
| | | // å¿
é¡»è¦å®ç°çè彿°ï¼å¨æ¤åå§åPinå表 |
| | | // å¿
é¡»è¦å®ç°çè彿°ï¼å¨æ¤åå§åPinå表 |
| | | void CLoadPort::initPins() |
| | | { |
| | | // å å
¥Pinåå§å代ç |
| | | // å å
¥Pinåå§å代ç |
| | | LOGD("<CLoadPort>initPins"); |
| | | addPin(SERVO::PinType::INPUT, _T("In")); |
| | | addPin(SERVO::PinType::OUTPUT, _T("Out")); |
| | | } |
| | | |
| | | // å¿
é¡»è¦å®ç°çè彿°ï¼å¨æ¤åå§åSlotä¿¡æ¯ |
| | | // å¿
é¡»è¦å®ç°çè彿°ï¼å¨æ¤åå§åSlotä¿¡æ¯ |
| | | void CLoadPort::initSlots() |
| | | { |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | |
| | | CEquipment::onTimer(nTimerid); |
| | | |
| | | |
| | | // ä»é
置读åºçenableï¼åå§åæ¶åç»efem |
| | | // ä»é
置读åºçenableï¼åå§åæ¶åç»efem |
| | | static int i_enable[4] = { 0 }; |
| | | if ((++i_enable[m_nIndex]) == 20 + m_nIndex) { |
| | | eablePort(m_bEnable, [&](int code) -> int { |
| | |
| | | |
| | | |
| | | |
| | | // æ¨¡ææµè¯ |
| | | // æ¨¡ææµè¯ |
| | | /* |
| | | if (m_nIndex == 0) { |
| | | static int ii = 0; |
| | |
| | | m_portStatusReport.copyEx(portStatusReport); |
| | | |
| | | |
| | | // å½portç¶æä¸ºInUse, æ¯è¾map |
| | | // å½portç¶æä¸ºInUse, æ¯è¾map |
| | | if (m_portStatusReport.getPortStatus() == PORT_INUSE) { |
| | | if (m_isCompareMapsBeforeProceeding) { |
| | | short scanMap = getScanCassetteMap(); |
| | | short downloadMap = getDownloadCassetteMap(); |
| | | if (scanMap == downloadMap) { |
| | | generateGlassList(scanMap); |
| | | this->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr); |
| | | } |
| | | else { |
| | | this->sendCassetteCtrlCmd(CCC_PROCESS_CANCEL, nullptr, 0, 0, 0, nullptr, nullptr); |
| | | // çæç»çåè¡¨ï¼æ¥èª EFEM æ«æå°ç map |
| | | generateGlassList(getScanCassetteMap()); |
| | | |
| | | // æåºå°åºç¨å±åæç¤º |
| | | if (m_listener.onMapMismatch != nullptr) { |
| | | m_listener.onMapMismatch(this, scanMap, downloadMap); |
| | | } |
| | | } |
| | | } |
| | | else { |
| | | // æåºå°åºç¨å±åéæ©è¦å å·¥ççå |
| | | generateGlassList(getScanCassetteMap()); |
| | | // CompareMapsBeforeProceedingï¼ä¸å¨æ¤å¤èªå¨ Start/Cancelï¼æ¹ä¸ºçå¾
Host å³çï¼ProceedWithCarrier/ProceedWithSlotMap/CarrierReleaseï¼ |
| | | // Host å³çå
¥å£ï¼S3F17 CarrierAction -> listener.onCarrierAction -> CMaster::proceedWithCarrier()/carrierRelease() |
| | | if (m_isCompareMapsBeforeProceeding) { |
| | | // è¿éä»
çå¾
ï¼å
·ä½ä¸æ¥ç±ä¸å±å¨ PORT_INUSE äºä»¶ä¸è§¦åï¼S6F11 CheckSlotMapï¼ |
| | | } |
| | | } |
| | | if (m_listener.onPortStatusChanged != nullptr) { |
| | |
| | | } |
| | | |
| | | |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | unsigned int weight = 201; |
| | | CAttributeVector& attrubutes = pStep->attributeVector(); |
| | | m_portStatusReport.getAttributeVector(attrubutes, weight); |
| | |
| | | return -1; |
| | | } |
| | | |
| | | LOGI("<CLoadPort-%d>åå¤è®¾ç½®Port type<%d>", m_nIndex, (int)type); |
| | | LOGI("<CLoadPort-%d>åå¤è®¾ç½®Port type<%d>", m_nIndex, (int)type); |
| | | short value = (short)type; |
| | | pStep->writeDataEx((const char*)&value, sizeof(short), [&, onWritedBlock](int code) -> int { |
| | | // test |
| | | code = WOK; |
| | | if (code == WOK) { |
| | | m_portType = type; |
| | | LOGI("<CLoadPort-%d>设置Port typeæå.", m_nIndex); |
| | | LOGI("<CLoadPort-%d>设置Port typeæå.", m_nIndex); |
| | | } |
| | | else { |
| | | LOGE("<CLoadPort-%d>设置Port type失败ï¼code:%d", m_nIndex, code); |
| | | LOGE("<CLoadPort-%d>设置Port type失败ï¼code:%d", m_nIndex, code); |
| | | } |
| | | if (onWritedBlock != nullptr) { |
| | | return onWritedBlock(code); |
| | |
| | | return -1; |
| | | } |
| | | |
| | | LOGI("<CLoadPort-%d>åå¤%s Port", m_nIndex, bEnable ? _T("å¯ç¨") : _T("ç¦ç¨")); |
| | | LOGI("<CLoadPort-%d>åå¤%s Port", m_nIndex, bEnable ? _T("å¯ç¨") : _T("ç¦ç¨")); |
| | | short value = bEnable ? 1 : 2; |
| | | pStep->writeDataEx((const char*)&value, sizeof(short), [&, onWritedBlock](int code) -> int { |
| | | // test |
| | | code = WOK; |
| | | if (code == WOK) { |
| | | m_bEnable = bEnable; |
| | | LOGI("<CLoadPort-%d>%s Portæå.", m_nIndex, bEnable ? _T("å¯ç¨") : _T("ç¦ç¨")); |
| | | LOGI("<CLoadPort-%d>%s Portæå.", m_nIndex, bEnable ? _T("å¯ç¨") : _T("ç¦ç¨")); |
| | | } |
| | | else { |
| | | LOGE("<CLoadPort-%d>%s Port失败ï¼code:%d", m_nIndex, bEnable ? _T("å¯ç¨") : _T("ç¦ç¨"), code); |
| | | LOGE("<CLoadPort-%d>%s Port失败ï¼code:%d", m_nIndex, bEnable ? _T("å¯ç¨") : _T("ç¦ç¨"), code); |
| | | } |
| | | if (onWritedBlock != nullptr) { |
| | | return onWritedBlock(code); |
| | |
| | | return -1; |
| | | } |
| | | |
| | | LOGI("<CLoadPort-%d>åå¤è®¾ç½®Port mode<%d>", m_nIndex, (int)mode); |
| | | LOGI("<CLoadPort-%d>åå¤è®¾ç½®Port mode<%d>", m_nIndex, (int)mode); |
| | | short value = (short)mode; |
| | | pStep->writeDataEx((const char*)&value, sizeof(short), [&, onWritedBlock](int code) -> int { |
| | | // test |
| | | code = WOK; |
| | | if (code == WOK) { |
| | | m_portMode = mode; |
| | | LOGI("<CLoadPort-%d>设置Port modeæå.", m_nIndex); |
| | | LOGI("<CLoadPort-%d>设置Port modeæå.", m_nIndex); |
| | | } |
| | | else { |
| | | LOGE("<CLoadPort-%d>设置Port mode失败ï¼code:%d", m_nIndex, code); |
| | | LOGE("<CLoadPort-%d>设置Port mode失败ï¼code:%d", m_nIndex, code); |
| | | } |
| | | if (onWritedBlock != nullptr) { |
| | | return onWritedBlock(code); |
| | |
| | | return -1; |
| | | } |
| | | |
| | | LOGI("<CLoadPort-%d>åå¤è®¾ç½®Cassette Type<%d>", m_nIndex, (int)type); |
| | | LOGI("<CLoadPort-%d>åå¤è®¾ç½®Cassette Type<%d>", m_nIndex, (int)type); |
| | | short value = (short)type; |
| | | pStep->writeDataEx((const char*)&value, sizeof(short), [&, onWritedBlock](int code) -> int { |
| | | // test |
| | | code = WOK; |
| | | if (code == WOK) { |
| | | LOGI("<CLoadPort-%d>设置Cassette Typeæå.", m_nIndex); |
| | | LOGI("<CLoadPort-%d>设置Cassette Typeæå.", m_nIndex); |
| | | } |
| | | else { |
| | | LOGE("<CLoadPort-%d>设置Cassette Type失败ï¼code:%d", m_nIndex, code); |
| | | LOGE("<CLoadPort-%d>设置Cassette Type失败ï¼code:%d", m_nIndex, code); |
| | | } |
| | | if (onWritedBlock != nullptr) { |
| | | return onWritedBlock(code); |
| | |
| | | return -1; |
| | | } |
| | | |
| | | LOGI("<CLoadPort-%d>åå¤è®¾ç½®Transfer mode<%d>", m_nIndex, (int)mode); |
| | | LOGI("<CLoadPort-%d>åå¤è®¾ç½®Transfer mode<%d>", m_nIndex, (int)mode); |
| | | short value = (short)mode; |
| | | pStep->writeDataEx((const char*)&value, sizeof(short), [&, onWritedBlock](int code) -> int { |
| | | // test |
| | | code = WOK; |
| | | if (code == WOK) { |
| | | m_transferMode = mode; |
| | | LOGI("<CLoadPort-%d>设置Transfer modeæå.", m_nIndex + 1); |
| | | LOGI("<CLoadPort-%d>设置Transfer modeæå.", m_nIndex + 1); |
| | | } |
| | | else { |
| | | LOGE("<CLoadPort-%d>设置Transfer mode失败ï¼code:%d", m_nIndex + 1, code); |
| | | LOGE("<CLoadPort-%d>设置Transfer mode失败ï¼code:%d", m_nIndex + 1, code); |
| | | } |
| | | if (onWritedBlock != nullptr) { |
| | | return onWritedBlock(code); |
| | |
| | | return -1; |
| | | } |
| | | |
| | | LOGI("<CLoadPort-%d>åå¤%s Auto Change", m_nIndex, bEnable ? _T("å¯ç¨") : _T("ç¦ç¨")); |
| | | LOGI("<CLoadPort-%d>åå¤%s Auto Change", m_nIndex, bEnable ? _T("å¯ç¨") : _T("ç¦ç¨")); |
| | | short value = bEnable ? 1 : 2; |
| | | pStep->writeDataEx((const char*)&value, sizeof(short), [&, onWritedBlock](int code) -> int { |
| | | // test |
| | | code = WOK; |
| | | if (code == WOK) { |
| | | m_bAutoChangeEnable = bEnable; |
| | | LOGI("<CLoadPort-%d>%s Auto Changeæå.", m_nIndex, bEnable ? _T("å¯ç¨") : _T("ç¦ç¨")); |
| | | LOGI("<CLoadPort-%d>%s Auto Changeæå.", m_nIndex, bEnable ? _T("å¯ç¨") : _T("ç¦ç¨")); |
| | | } |
| | | else { |
| | | LOGE("<CLoadPort-%d>%s Auto Change失败ï¼code:%d", m_nIndex, bEnable ? _T("å¯ç¨") : _T("ç¦ç¨"), code); |
| | | LOGE("<CLoadPort-%d>%s Auto Change失败ï¼code:%d", m_nIndex, bEnable ? _T("å¯ç¨") : _T("ç¦ç¨"), code); |
| | | } |
| | | if (onWritedBlock != nullptr) { |
| | | return onWritedBlock(code); |
| | |
| | | |
| | | short CLoadPort::getDownloadCassetteMap() |
| | | { |
| | | // ææ¶æªå®ç°æ¤åè½ |
| | | short map = 0; |
| | | return map; |
| | | return m_downloadCassetteMap; |
| | | } |
| | | |
| | | void CLoadPort::setDownloadCassetteMap(short map) |
| | | { |
| | | m_downloadCassetteMap = map; |
| | | } |
| | | |
| | | /* |
| | | * çææµè¯ç¨çç»çå表 |
| | | * çææµè¯ç¨çç»çå表 |
| | | */ |
| | | int CLoadPort::testGenerateGlassList(MaterialsType type) |
| | | { |
| | | // 妿é空就ä¸çæäº |
| | | // 妿é空就ä¸çæäº |
| | | Lock(); |
| | | if (hasGlass()) { |
| | | Unlock(); |
| | |
| | | } |
| | | |
| | | /* |
| | | * æ ¹æ®efemæ«æå°çmapï¼çæç»çå表 |
| | | * æ ¹æ®efemæ«æå°çmapï¼çæç»çå表 |
| | | */ |
| | | int CLoadPort::generateGlassList(short map) |
| | | { |
| | | // å
éæ¾è¾æ©åçæ°æ® |
| | | // å
éæ¾è¾æ©åçæ°æ® |
| | | Lock(); |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | m_slot[i].setContext(nullptr); |
| | |
| | | Unlock(); |
| | | |
| | | |
| | | // æ ¹æ®mapçææ°ç |
| | | // æ ¹æ®mapçææ°ç |
| | | char szBuffer[64]; |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | if (!m_slot[i].isEnable()) continue; |
| | |
| | | { |
| | | m_isCompareMapsBeforeProceeding = bCompare; |
| | | } |
| | | |
| | | BOOL CLoadPort::isCompareMapsBeforeProceeding() const |
| | | { |
| | | return m_isCompareMapsBeforeProceeding; |
| | | } |
| | | } |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include "CEquipment.h" |
| | | #include "ServoCommo.h" |
| | | |
| | |
| | | void localAutoChangeEnable(BOOL bEnable); |
| | | short getScanCassetteMap(); |
| | | short getDownloadCassetteMap(); |
| | | void setDownloadCassetteMap(short map); |
| | | |
| | | public: |
| | | short getNextCassetteSequenceNo(); |
| | |
| | | ONWRITED onWritedBlock); |
| | | CStep* getCassetteCtrlCmdStep(); |
| | | void setCompareMapsBeforeProceeding(BOOL bCompare); |
| | | BOOL isCompareMapsBeforeProceeding() const; |
| | | |
| | | private: |
| | | int decodePortStatusReport(CStep* pStep, const char* pszData, size_t size); |
| | |
| | | CPortStatusReport m_portStatusReport; |
| | | int m_nNextCassetteSequenceNo; |
| | | |
| | | // å¨å¼å§å·¥èºåæ¯å¦å
éè¦å
æ¯è¾map |
| | | // å¨å¼å§å·¥èºåæ¯å¦å
éè¦å
æ¯è¾map |
| | | BOOL m_isCompareMapsBeforeProceeding; |
| | | short m_downloadCassetteMap; |
| | | }; |
| | | } |
| | | |
| | |
| | | } |
| | | m_processJobs = temp; |
| | | |
| | | // éç½®åç«¯å£ DownloadMapï¼Host/æ¬å°å¾éçææå 工槽ä½ï¼ |
| | | for (int i = 0; i < 4; i++) { |
| | | auto* pPort = (CLoadPort*)getEquipment(EQ_ID_LOADPORT1 + i); |
| | | if (pPort != nullptr) { |
| | | pPort->setDownloadCassetteMap(0); |
| | | } |
| | | } |
| | | |
| | | |
| | | // æ´æ°context |
| | | std::vector<uint8_t> newSlots; |
| | | std::vector<void*> newContexts; |
| | | for (auto pj : m_processJobs) { |
| | | for (auto& c : pj->carriers()) { |
| | | auto pPort = getPortWithCarrierId(c.carrierId); |
| | | if (pPort == nullptr) continue; |
| | | |
| | | short downloadMap = 0; |
| | | for (auto s : c.slots) { |
| | | if (s >= 1 && s <= 8) { |
| | | downloadMap |= (short)(1 << (s - 1)); |
| | | } |
| | | } |
| | | pPort->setDownloadCassetteMap((short)(pPort->getDownloadCassetteMap() | downloadMap)); |
| | | |
| | | std::vector<uint8_t> newSlots; |
| | | std::vector<void*> newContexts; |
| | | for (auto s : c.slots) { |
| | | auto pGlass = pPort->getGlassFromSlot(s); |
| | | if (pGlass == nullptr) continue; |
| | |
| | | SetDlgItemText(IDC_BUTTON_CIM, pszText); |
| | | } |
| | | |
| | | void CMyStatusbar::setCurTaskBtnColors(COLORREF face, COLORREF frame, COLORREF text) |
| | | { |
| | | m_btnCurTask.SetFaceColor(face); |
| | | m_btnCurTask.SetFrameColor(frame); |
| | | m_btnCurTask.SetTextColor(text); |
| | | Invalidate(); |
| | | UpdateWindow(); |
| | | } |
| | | |
| | | void CMyStatusbar::setCimBtnColors(COLORREF face, COLORREF frame, COLORREF text) |
| | | { |
| | | m_btnCim.SetFaceColor(face); |
| | | m_btnCim.SetFrameColor(frame); |
| | | m_btnCim.SetTextColor(text); |
| | | Invalidate(); |
| | | UpdateWindow(); |
| | | } |
| | | |
| | | BOOL CMyStatusbar::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | |
| | | m_btnCurTask.SetFrameColor(m_crBkgnd); |
| | | m_btnCurTask.SetFrameColor(BS_HOVER, RGB(218, 218, 218)); |
| | | m_btnCurTask.SetFrameColor(BS_PRESS, RGB(168, 168, 168)); |
| | | m_btnCurTask.SetTextColor(m_crForeground); |
| | | |
| | | m_btnCim.SubclassDlgItem(IDC_BUTTON_CIM, this); |
| | | m_btnCim.SetFaceColor(m_crBkgnd); |
| | | m_btnCim.SetFrameColor(m_crBkgnd); |
| | | m_btnCim.SetFrameColor(BS_HOVER, RGB(218, 218, 218)); |
| | | m_btnCim.SetFrameColor(BS_PRESS, RGB(168, 168, 168)); |
| | | m_btnCim.SetTextColor(m_crForeground); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | |
| | | pItem->GetClientRect(rcItem); |
| | | pItem->MoveWindow(x, (rcClient.Height() - rcItem.Height()) / 2, rcItem.Width(), rcItem.Height()); |
| | | x += rcItem.Width(); |
| | | } |
| | | } |
| | |
| | | void setRunTimeText(const char* pszText); |
| | | void setCurTaskBtnText(const char* pszText); |
| | | void setCimBtnText(const char* pszText); |
| | | void setCurTaskBtnColors(COLORREF face, COLORREF frame, COLORREF text); |
| | | void setCimBtnColors(COLORREF face, COLORREF frame, COLORREF text); |
| | | |
| | | private: |
| | | void Resize(); |
| | |
| | | return m_nPanelWidth; |
| | | } |
| | | |
| | | void CPanelMaster::setPanelWidth(int width) |
| | | { |
| | | m_nPanelWidth = width; |
| | | } |
| | | |
| | | BOOL CPanelMaster::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | |
| | | pLine1->SetBkgndColor(RGB(225, 225, 225)); |
| | | pLine1->SetLineColor(RGB(198, 198, 198)); |
| | | pLine1->EnableResize(); |
| | | |
| | | |
| | | // 读å颿¿å®½ |
| | | CString strIniFile; |
| | | strIniFile.Format(_T("%s\\%s.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir, (LPTSTR)(LPCTSTR)theApp.m_strAppFile); |
| | | m_nPanelWidth = GetPrivateProfileInt(_T("App"), _T("MasterPanelWidth"), |
| | | int((double)GetSystemMetrics(SM_CXSCREEN) * 0.25), (LPTSTR)(LPCTSTR)strIniFile); |
| | | |
| | | |
| | | // treectrl |
| | |
| | | m_nPanelWidth = max(m_nPanelWidth, MASTER_PANEL_MIN_WIDTH); |
| | | m_nPanelWidth = min(m_nPanelWidth, MASTER_PANEL_MAX_WIDTH); |
| | | GetParent()->SendMessage(ID_MSG_PANEL_RESIZE, m_nPanelWidth, 0); |
| | | |
| | | CString strIniFile, strValue; |
| | | strIniFile.Format(_T("%s\\%s.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir, (LPTSTR)(LPCTSTR)theApp.m_strAppFile); |
| | | strValue.Format(_T("%d"), m_nPanelWidth); |
| | | WritePrivateProfileString(_T("App"), _T("MasterPanelWidth"), |
| | | (LPTSTR)(LPCTSTR)strValue, (LPTSTR)(LPCTSTR)strIniFile); |
| | | OnSize(0, 0, 0); |
| | | |
| | | * result = 0; |
| | |
| | | CPanelMaster(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CPanelMaster(); |
| | | int getPanelWidth(); |
| | | void setPanelWidth(int width); |
| | | void loadEquipmentList(); |
| | | void loadSteps(SERVO::CEquipment* pEquipment, HTREEITEM hItemEq); |
| | | SERVO::CEquipment* GetActiveEquipment(); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // CPanelProduction.cpp |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "CPanelProduction.h" |
| | | #include "afxdialogex.h" |
| | | #include "Common.h" |
| | | #include "VerticalLine.h" |
| | | |
| | | |
| | | // CPanelProduction dialog |
| | | |
| | | IMPLEMENT_DYNAMIC(CPanelProduction, CDialogEx) |
| | | |
| | | CPanelProduction::CPanelProduction(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_PANEL_PRODUCTION, pParent) |
| | | { |
| | | m_crBkgnd = PANEL_PRODUCTION_BACKGROUND_COLOR; |
| | | m_hbrBkgnd = nullptr; |
| | | m_nPanelWidth = 288; |
| | | m_hPlaceholder = nullptr; |
| | | m_bShiftSummaryValid = FALSE; |
| | | m_pStatsThread = nullptr; |
| | | } |
| | | |
| | | CPanelProduction::~CPanelProduction() |
| | | { |
| | | } |
| | | |
| | | void CPanelProduction::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CPanelProduction, CDialogEx) |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_DESTROY() |
| | | ON_WM_SIZE() |
| | | ON_NOTIFY(BYVERTICALLINE_MOVEX, IDC_LINE1, &CPanelProduction::OnVLineMoveX) |
| | | ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CPanelProduction::OnBnClickedButtonClose) |
| | | ON_WM_TIMER() |
| | | END_MESSAGE_MAP() |
| | | |
| | | int CPanelProduction::getPanelWidth() |
| | | { |
| | | return m_nPanelWidth; |
| | | } |
| | | |
| | | void CPanelProduction::setPanelWidth(int width) |
| | | { |
| | | m_nPanelWidth = width; |
| | | } |
| | | |
| | | BOOL CPanelProduction::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | CVerticalLine* pLine1 = CVerticalLine::Hook(GetDlgItem(IDC_LINE1)->GetSafeHwnd()); |
| | | pLine1->SetBkgndColor(RGB(225, 225, 225)); |
| | | pLine1->SetLineColor(RGB(198, 198, 198)); |
| | | pLine1->EnableResize(); |
| | | |
| | | SetTimer(1, 1000 * 10, nullptr); |
| | | StartStatsThread(); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // Exception: OCX property pages should return FALSE |
| | | } |
| | | |
| | | HBRUSH CPanelProduction::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) |
| | | { |
| | | HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); |
| | | |
| | | if (nCtlColor == CTLCOLOR_STATIC) { |
| | | pDC->SetBkColor(m_crBkgnd); |
| | | pDC->SetTextColor(RGB(0, 0, 0)); |
| | | } |
| | | |
| | | if (m_hbrBkgnd == nullptr) { |
| | | m_hbrBkgnd = CreateSolidBrush(m_crBkgnd); |
| | | } |
| | | |
| | | return m_hbrBkgnd; |
| | | } |
| | | |
| | | void CPanelProduction::OnDestroy() |
| | | { |
| | | StopStatsThread(); |
| | | |
| | | CDialogEx::OnDestroy(); |
| | | |
| | | if (m_hbrBkgnd != nullptr) { |
| | | ::DeleteObject(m_hbrBkgnd); |
| | | } |
| | | } |
| | | |
| | | void CPanelProduction::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | if (GetDlgItem(IDC_LINE1) == nullptr) return; |
| | | |
| | | CWnd* pItem; |
| | | CRect rcClient, rcItem; |
| | | |
| | | GetClientRect(&rcClient); |
| | | pItem = GetDlgItem(IDC_LINE1); |
| | | pItem->MoveWindow(rcClient.right - 3, 0, 3, rcClient.Height()); |
| | | } |
| | | |
| | | #define PRODUCTION_PANEL_MIN_WIDTH 88 |
| | | #define PRODUCTION_PANEL_MAX_WIDTH 588 |
| | | void CPanelProduction::OnVLineMoveX(NMHDR* nmhdr, LRESULT* result) |
| | | { |
| | | BYVERTICALLINE_NMHDR* pNmhdrex = (BYVERTICALLINE_NMHDR*)nmhdr; |
| | | int x = pNmhdrex->dwData; |
| | | m_nPanelWidth += x; |
| | | m_nPanelWidth = max(m_nPanelWidth, PRODUCTION_PANEL_MIN_WIDTH); |
| | | m_nPanelWidth = min(m_nPanelWidth, PRODUCTION_PANEL_MAX_WIDTH); |
| | | GetParent()->SendMessage(ID_MSG_PANEL_RESIZE, m_nPanelWidth, 0); |
| | | OnSize(0, 0, 0); |
| | | |
| | | *result = 0; |
| | | } |
| | | |
| | | void CPanelProduction::OnBnClickedButtonClose() |
| | | { |
| | | CWnd* pParent = GetParent(); |
| | | if (pParent != nullptr) { |
| | | pParent->PostMessage(WM_COMMAND, ID_MENU_WND_TEST_PANEL, 0); |
| | | } |
| | | } |
| | | |
| | | BOOL CPanelProduction::TryGetShiftSummary(ProductionShiftSummary& outSummary) |
| | | { |
| | | CSingleLock lock(&m_csShiftSummary, TRUE); |
| | | if (!m_bShiftSummaryValid) return FALSE; |
| | | outSummary = m_shiftSummary; |
| | | return TRUE; |
| | | } |
| | | |
| | | void CPanelProduction::StartStatsThread() |
| | | { |
| | | if (m_pStatsThread != nullptr) return; |
| | | |
| | | m_evStopStats.ResetEvent(); |
| | | |
| | | m_pStatsThread = AfxBeginThread(&CPanelProduction::StatsThreadProc, this, THREAD_PRIORITY_BELOW_NORMAL, 0, 0); |
| | | if (m_pStatsThread != nullptr) { |
| | | m_pStatsThread->m_bAutoDelete = FALSE; |
| | | } |
| | | } |
| | | |
| | | void CPanelProduction::StopStatsThread() |
| | | { |
| | | if (m_pStatsThread == nullptr) return; |
| | | |
| | | m_evStopStats.SetEvent(); |
| | | const DWORD rc = WaitForSingleObject(m_pStatsThread->m_hThread, 5000); |
| | | if (rc == WAIT_OBJECT_0) { |
| | | delete m_pStatsThread; |
| | | } |
| | | m_pStatsThread = nullptr; |
| | | } |
| | | |
| | | UINT CPanelProduction::StatsThreadProc(LPVOID pParam) |
| | | { |
| | | CPanelProduction* self = reinterpret_cast<CPanelProduction*>(pParam); |
| | | if (self == nullptr) return 0; |
| | | |
| | | const DWORD intervalMs = 5000; |
| | | for (;;) { |
| | | if (self->m_evStopStats.Lock(intervalMs)) break; |
| | | |
| | | ProductionShiftSummary summary; |
| | | if (ProductionStats::ComputeCurrentShiftSummary(theApp.m_model.m_configuration, summary)) { |
| | | CSingleLock lock(&self->m_csShiftSummary, TRUE); |
| | | self->m_shiftSummary = std::move(summary); |
| | | self->m_bShiftSummaryValid = TRUE; |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | void CPanelProduction::OnTimer(UINT_PTR nIDEvent) |
| | | { |
| | | // TODO: 卿¤æ·»å æ¶æ¯å¤çç¨åºä»£ç å/æè°ç¨é»è®¤å¼ |
| | | if (nIDEvent == 1) { |
| | | ProductionShiftSummary outSummary; |
| | | if (TryGetShiftSummary(outSummary)) { |
| | | TRACE("OnTimer outSummary.output.pairsPass:%d\n", outSummary.output.pairsPass); |
| | | } |
| | | } |
| | | |
| | | CDialogEx::OnTimer(nIDEvent); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "BlButton.h" |
| | | #include <afxmt.h> |
| | | |
| | | #include "ProductionStats.h" |
| | | |
| | | // CPanelProduction dialog |
| | | class CPanelProduction : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CPanelProduction) |
| | | |
| | | public: |
| | | CPanelProduction(CWnd* pParent = nullptr); // standard constructor |
| | | virtual ~CPanelProduction(); |
| | | int getPanelWidth(); |
| | | void setPanelWidth(int width); |
| | | |
| | | private: |
| | | COLORREF m_crBkgnd; |
| | | HBRUSH m_hbrBkgnd; |
| | | int m_nPanelWidth; |
| | | CBlButton m_btnClose; |
| | | HWND m_hPlaceholder; |
| | | |
| | | // Production shift summary (updated by background thread) |
| | | ProductionShiftSummary m_shiftSummary; |
| | | BOOL m_bShiftSummaryValid; |
| | | CCriticalSection m_csShiftSummary; |
| | | CWinThread* m_pStatsThread; |
| | | CEvent m_evStopStats; |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_PANEL_PRODUCTION }; |
| | | #endif |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); |
| | | afx_msg void OnDestroy(); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnVLineMoveX(NMHDR* nmhdr, LRESULT* result); |
| | | afx_msg void OnBnClickedButtonClose(); |
| | | |
| | | // Thread-safe snapshot for UI timer display |
| | | BOOL TryGetShiftSummary(ProductionShiftSummary& outSummary); |
| | | |
| | | private: |
| | | static UINT AFX_CDECL StatsThreadProc(LPVOID pParam); |
| | | void StartStatsThread(); |
| | | void StopStatsThread(); |
| | | public: |
| | | afx_msg void OnTimer(UINT_PTR nIDEvent); |
| | | }; |
| | |
| | | #define APPDLG_BACKGROUND_COLOR RGB(255, 255, 255) |
| | | #define LOGDLG_BACKGROUND_COLOR RGB(255, 255, 255) |
| | | #define PANEL_MASTER_BACKGROUND_COLOR RGB(255, 255, 255) |
| | | #define PANEL_PRODUCTION_BACKGROUND_COLOR RGB(255, 255, 255) |
| | | #define PANEL_ATTRIBUTES_BACKGROUND_COLOR RGB(255, 255, 255) |
| | | #define PANEL_EQUIPMENT_BACKGROUND_COLOR RGB(255, 255, 255) |
| | | #define PAGE_GRPAH1_BACKGROUND_COLOR RGB(255, 255, 255) |
| | |
| | | #define STATUSBAR_BK_STARTING RGB(58, 127, 78) |
| | | #define STATUSBAR_BK_RUNNING RGB(34, 177, 76) |
| | | #define STATUSBAR_BK_ALARM RGB(255, 127, 39) |
| | | #define CIM_STATUS_BK_SELECTED STATUSBAR_BK_RUNNING |
| | | #define CIM_STATUS_BK_DISCONNECTED STATUSBAR_BK_NORMAL |
| | | |
| | | /* LOG BTN */ |
| | | #define BTN_LOG_FRAME_NORMAL RGB(88, 88, 88) |
| | |
| | | int getPortCassetteSnSeed(int port); |
| | | void setPortCassetteSnSeed(int port, int seed); |
| | | |
| | | // Production shift settings |
| | | // Reads shift start times from ini. |
| | | // - [Production] DayShiftStart=HH:MM (default 08:00) |
| | | // - [Production] NightShiftStart=HH:MM (default DayShiftStart+12h) |
| | | // Returns TRUE if both values are valid (or derived); otherwise FALSE and falls back to defaults. |
| | | BOOL getProductionShiftStartMinutes(int& dayStartMinutes, int& nightStartMinutes); |
| | | |
| | | public: |
| | | void setP2RemoteEqReconnectInterval(int second); |
| | | int getP2RemoteEqReconnectInterval(); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "Configuration.h" |
| | | |
| | | #include <mutex> |
| | | #include <string> |
| | | #include <unordered_map> |
| | | |
| | | static bool TryParseHHMM(const std::string& text, int& outMinutes) |
| | | { |
| | | int hour = 0; |
| | | int minute = 0; |
| | | if (sscanf_s(text.c_str(), "%d:%d", &hour, &minute) != 2) return false; |
| | | if (hour < 0 || hour >= 24) return false; |
| | | if (minute < 0 || minute >= 60) return false; |
| | | outMinutes = hour * 60 + minute; |
| | | return true; |
| | | } |
| | | |
| | | BOOL CConfiguration::getProductionShiftStartMinutes(int& dayStartMinutes, int& nightStartMinutes) |
| | | { |
| | | struct CachedShift { |
| | | BOOL ok = FALSE; |
| | | int day = 0; |
| | | int night = 0; |
| | | bool inited = false; |
| | | }; |
| | | |
| | | static std::mutex s_mtx; |
| | | static std::unordered_map<std::string, CachedShift> s_cache; |
| | | |
| | | const std::string filePath((LPCSTR)(LPCTSTR)m_strFilepath); |
| | | { |
| | | std::lock_guard<std::mutex> g(s_mtx); |
| | | auto it = s_cache.find(filePath); |
| | | if (it != s_cache.end() && it->second.inited) { |
| | | dayStartMinutes = it->second.day; |
| | | nightStartMinutes = it->second.night; |
| | | return it->second.ok; |
| | | } |
| | | } |
| | | |
| | | char buf[64] = {}; |
| | | GetPrivateProfileStringA("Production", "DayShiftStart", "08:00", buf, (DWORD)sizeof(buf), m_strFilepath); |
| | | std::string dayStr(buf); |
| | | |
| | | GetPrivateProfileStringA("Production", "NightShiftStart", "", buf, (DWORD)sizeof(buf), m_strFilepath); |
| | | std::string nightStr(buf); |
| | | |
| | | const int kDefaultDay = 8 * 60; |
| | | const int kDefaultNight = 20 * 60; |
| | | |
| | | bool okDay = TryParseHHMM(dayStr, dayStartMinutes); |
| | | bool okNight = false; |
| | | if (!nightStr.empty()) okNight = TryParseHHMM(nightStr, nightStartMinutes); |
| | | |
| | | if (!okDay) dayStartMinutes = kDefaultDay; |
| | | if (!okNight) nightStartMinutes = (dayStartMinutes + 12 * 60) % (24 * 60); |
| | | |
| | | if (dayStartMinutes == nightStartMinutes) { |
| | | dayStartMinutes = kDefaultDay; |
| | | nightStartMinutes = kDefaultNight; |
| | | { |
| | | std::lock_guard<std::mutex> g(s_mtx); |
| | | s_cache[filePath] = CachedShift{ FALSE, dayStartMinutes, nightStartMinutes, true }; |
| | | } |
| | | return FALSE; |
| | | } |
| | | |
| | | const BOOL ok = (okDay && (nightStr.empty() ? TRUE : okNight)) ? TRUE : FALSE; |
| | | { |
| | | std::lock_guard<std::mutex> g(s_mtx); |
| | | s_cache[filePath] = CachedShift{ ok, dayStartMinutes, nightStartMinutes, true }; |
| | | } |
| | | return ok; |
| | | } |
| | |
| | | return requestEventReportSend("CarrierID_Readed"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_CheckSlotMap() |
| | | { |
| | | return requestEventReportSend("CheckSlotMap"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_SlotMapVerificationOK() |
| | | { |
| | | return requestEventReportSend("SlotMapVerificationOK"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_SlotMapVerificationNG() |
| | | { |
| | | return requestEventReportSend("SlotMapVerificationNG"); |
| | | } |
| | | |
| | | 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_Ready_To_Release() |
| | | { |
| | | return requestEventReportSend("Port_Ready_To_Release"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_Port_Blocked() |
| | |
| | | { |
| | | return requestEventReportSend("OCR_PanelID_Read_OK"); |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | int requestEventReportSend(unsigned int CEID); |
| | | int requestEventReportSend(const char* pszEventName); |
| | | int requestEventReportSend_CarrierID_Readed(); |
| | | int requestEventReportSend_CheckSlotMap(); |
| | | int requestEventReportSend_SlotMapVerificationOK(); |
| | | int requestEventReportSend_SlotMapVerificationNG(); |
| | | int requestEventReportSend_Port_Unload_Ready(); |
| | | int requestEventReportSend_Port_Load_Ready(); |
| | | int requestEventReportSend_Port_Ready_To_Release(); |
| | | int requestEventReportSend_Port_Blocked(); |
| | | int requestEventReportSend_PJ_Queued(); |
| | | int requestEventReportSend_PJ_Start(); |
| | |
| | | // Spooling Config |
| | | std::map<uint16_t, std::set<uint16_t>> m_spoolingConfig; |
| | | }; |
| | | |
| | |
| | | #include "TransferManager.h" |
| | | #include "RecipeManager.h" |
| | | #include "GlassLogDb.h" |
| | | #include <map> |
| | | |
| | | |
| | | CModel::CModel() |
| | |
| | | return CAACK_3; |
| | | } |
| | | |
| | | const unsigned int portIndex = PTN - 1; |
| | | SERVO::CLoadPort* pLoadPort = (SERVO::CLoadPort*)m_master.getEquipment(EQ_ID_LOADPORT1 + portIndex); |
| | | |
| | | if (_strcmpi(pszCarrierAction, "ProceedWithCarrier") == 0) { |
| | | m_master.proceedWithCarrier(PTN); |
| | | // ææ¡£æµç¨ï¼ProceedWithCarrier ä¹å设å¤è¿å
¥ Check SlotMapï¼WFHï¼ï¼ |
| | | // çæ£çâå¼å§âç± ProceedWithSlotMap å³ç触åã |
| | | // ä»
彿ªå¼å¯ CompareMapsBeforeProceeding æ¶ï¼ææ²¿ç¨æ§é»è¾ç´æ¥ Startã |
| | | if (pLoadPort == nullptr || !pLoadPort->isCompareMapsBeforeProceeding()) { |
| | | m_master.proceedWithCarrier(portIndex); |
| | | } |
| | | return CAACK_0; |
| | | } |
| | | else if (_strcmpi(pszCarrierAction, "ProceedWithSlotMap") == 0) { |
| | | // TODO(Hoståå): |
| | | // ææ¡£ä¸ ProceedWithSlotMap å¯è½ä¼æºå¸¦ LotID / PanelIDList / SlotMap çæ°æ®ï¼æå¤13çï¼ç¨äºæ ¼å¼æ ¡éªä¸ç»å®ã |
| | | // å½å S3F17 è§£æç»æä»
æ¯æ {DATAID, CarrierAction, CarrierID, PTN}ï¼å°æªå®ç°ä¸è¿°æ©å±å段çè§£æ/æ ¡éªã |
| | | // æªæ¥è¥å®¢æ·ç¡®è®¤ SECS-II ç»æï¼éè¦å¨ CHsmsPassive::replyCarrierAction() æ©å±è§£æå¹¶å¨æ¤å¤è½åº/æ ¡éªã |
| | | // ä»
å¨ CompareMapsBeforeProceeding å¯ç¨ï¼Host 模å¼ï¼ä¸å
许æ¤å¨ä½ |
| | | if (pLoadPort == nullptr || !pLoadPort->isCompareMapsBeforeProceeding()) { |
| | | strErrorTxt = "rejected - SlotMap check disabled"; |
| | | return CAACK_5; |
| | | } |
| | | |
| | | m_hsmsPassive.setVariableValue("SlotMapScan", pLoadPort->getScanCassetteMap()); |
| | | m_hsmsPassive.setVariableValue("SlotMapDownload", pLoadPort->getDownloadCassetteMap()); |
| | | m_hsmsPassive.requestEventReportSend_SlotMapVerificationOK(); |
| | | |
| | | // Host 确认 SlotMap ååå¼å§å å·¥/æµç¨ |
| | | m_master.proceedWithCarrier(portIndex); |
| | | return CAACK_0; |
| | | } |
| | | else if (_strcmpi(pszCarrierAction, "CarrierRelease") == 0) { |
| | | m_master.carrierRelease(PTN); |
| | | m_master.carrierRelease(portIndex); |
| | | return CAACK_0; |
| | | } |
| | | |
| | |
| | | masterListener.onEqVcrEventReport = [&](void* pMaster, SERVO::CEquipment* pEquipment, SERVO::CVcrEventReport* pReport) { |
| | | LOGE("<CModel>onEqVcrEventReport."); |
| | | if (pReport != nullptr) { |
| | | m_hsmsPassive.setVariableValue("PanelStartID", pReport->getGlassId().c_str()); |
| | | 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.onLoadPortStatusChanged = [&] (void* pMaster, SERVO::CEquipment* pEquipment, short status, __int64 data) { |
| | | LOGE("<CModel>onLoadPortStatusChanged. status = %d", status); |
| | | static std::map<int, short> s_prevPortStatus; |
| | | const int eqId = (pEquipment != nullptr) ? pEquipment->getID() : 0; |
| | | const short prevStatus = s_prevPortStatus[eqId]; |
| | | s_prevPortStatus[eqId] = status; |
| | | 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.requestEventReportSend_CarrierID_Readed(); |
| | | } |
| | |
| | | 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.requestEventReportSend_Port_Unload_Ready(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "ProductionStats.h" |
| | | |
| | | #include <algorithm> |
| | | #include <ctime> |
| | | #include <iomanip> |
| | | #include <sstream> |
| | | #include <unordered_map> |
| | | |
| | | #include "Configuration.h" |
| | | #include "Log.h" |
| | | #include "sqlite3.h" |
| | | |
| | | #ifdef min |
| | | #undef min |
| | | #endif |
| | | #ifdef max |
| | | #undef max |
| | | #endif |
| | | |
| | | static std::string FormatLocal(const std::chrono::system_clock::time_point& tp) |
| | | { |
| | | const std::time_t tt = std::chrono::system_clock::to_time_t(tp); |
| | | std::tm tm{}; |
| | | localtime_s(&tm, &tt); |
| | | std::ostringstream oss; |
| | | oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S"); |
| | | return oss.str(); |
| | | } |
| | | |
| | | static std::string FormatUtcIso(const std::chrono::system_clock::time_point& tp) |
| | | { |
| | | const std::time_t tt = std::chrono::system_clock::to_time_t(tp); |
| | | std::tm tm{}; |
| | | gmtime_s(&tm, &tt); |
| | | std::ostringstream oss; |
| | | oss << std::put_time(&tm, "%Y-%m-%dT%H:%M:%SZ"); |
| | | return oss.str(); |
| | | } |
| | | |
| | | static bool TryParseLocalTime(const std::string& text, std::chrono::system_clock::time_point& outTp) |
| | | { |
| | | if (text.empty()) return false; |
| | | std::tm tm{}; |
| | | std::istringstream iss(text); |
| | | iss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S"); |
| | | if (iss.fail()) return false; |
| | | tm.tm_isdst = -1; |
| | | const std::time_t tt = mktime(&tm); |
| | | if (tt == (time_t)-1) return false; |
| | | outTp = std::chrono::system_clock::from_time_t(tt); |
| | | return true; |
| | | } |
| | | |
| | | static std::string GetExeDir() |
| | | { |
| | | char path[MAX_PATH] = {}; |
| | | GetModuleFileNameA(nullptr, path, MAX_PATH); |
| | | std::string exePath(path); |
| | | const size_t pos = exePath.find_last_of("\\/"); |
| | | return (pos == std::string::npos) ? std::string() : exePath.substr(0, pos); |
| | | } |
| | | |
| | | static bool FileExistsA(const std::string& path) |
| | | { |
| | | const DWORD attr = GetFileAttributesA(path.c_str()); |
| | | return (attr != INVALID_FILE_ATTRIBUTES) && ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0); |
| | | } |
| | | |
| | | static std::string PickDbPath(const std::string& rel1, const std::string& rel2) |
| | | { |
| | | const std::string base = GetExeDir(); |
| | | const std::string p1 = base + "\\" + rel1; |
| | | if (FileExistsA(p1)) return p1; |
| | | return base + "\\" + rel2; |
| | | } |
| | | |
| | | static void ComputeOutputFromProcessDb( |
| | | const ProductionShiftWindow& win, |
| | | ProductionOutputSummary& out) |
| | | { |
| | | const std::string dbPath = PickDbPath("db\\process.db", "DB\\process.db"); |
| | | |
| | | sqlite3* db = nullptr; |
| | | if (sqlite3_open_v2(dbPath.c_str(), &db, SQLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX, nullptr) != SQLITE_OK) { |
| | | if (db) sqlite3_close(db); |
| | | return; |
| | | } |
| | | |
| | | const char* sql = |
| | | "SELECT class_id, buddy_id, aoi_result " |
| | | "FROM glass_log " |
| | | "WHERE t_end IS NOT NULL AND t_end >= ? AND t_end < ?;"; |
| | | |
| | | sqlite3_stmt* stmt = nullptr; |
| | | if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) { |
| | | sqlite3_close(db); |
| | | return; |
| | | } |
| | | |
| | | sqlite3_bind_text(stmt, 1, win.startUtcIso.c_str(), -1, SQLITE_TRANSIENT); |
| | | sqlite3_bind_text(stmt, 2, win.endUtcIso.c_str(), -1, SQLITE_TRANSIENT); |
| | | |
| | | struct PairAgg { |
| | | bool hasPass = false; |
| | | bool hasFail = false; |
| | | bool hasNo = false; |
| | | }; |
| | | std::unordered_map<std::string, PairAgg> pairs; |
| | | |
| | | for (;;) { |
| | | const int rc = sqlite3_step(stmt); |
| | | if (rc == SQLITE_ROW) { |
| | | const char* classId = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)); |
| | | const char* buddyId = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)); |
| | | const int aoi = sqlite3_column_int(stmt, 2); |
| | | |
| | | const std::string a = classId ? classId : ""; |
| | | const std::string b = buddyId ? buddyId : ""; |
| | | std::string key; |
| | | if (!b.empty()) { |
| | | if (a <= b) key = a + "|" + b; |
| | | else key = b + "|" + a; |
| | | } |
| | | else { |
| | | key = a; |
| | | } |
| | | |
| | | auto& agg = pairs[key]; |
| | | if (aoi == 1) agg.hasPass = true; |
| | | else if (aoi == 2) agg.hasFail = true; |
| | | else agg.hasNo = true; |
| | | } |
| | | else if (rc == SQLITE_DONE) { |
| | | break; |
| | | } |
| | | else { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | sqlite3_finalize(stmt); |
| | | sqlite3_close(db); |
| | | |
| | | out.pairsTotal = static_cast<long long>(pairs.size()); |
| | | for (const auto& kv : pairs) { |
| | | const auto& agg = kv.second; |
| | | if (agg.hasFail) out.pairsFail++; |
| | | else if (agg.hasPass) out.pairsPass++; |
| | | else out.pairsNoResult++; |
| | | } |
| | | const long long denom = out.pairsPass + out.pairsFail; |
| | | out.yield = (denom > 0) ? (static_cast<double>(out.pairsPass) / static_cast<double>(denom)) : 0.0; |
| | | } |
| | | |
| | | static void ComputeAlarmSummaryFromDb( |
| | | const ProductionShiftWindow& win, |
| | | ProductionAlarmSummary& out) |
| | | { |
| | | const std::string dbPath = PickDbPath("DB\\AlarmManager.db", "DB\\AlarmManager.db"); |
| | | sqlite3* db = nullptr; |
| | | if (sqlite3_open_v2(dbPath.c_str(), &db, SQLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX, nullptr) != SQLITE_OK) { |
| | | if (db) sqlite3_close(db); |
| | | return; |
| | | } |
| | | |
| | | // 1) triggered within shift |
| | | { |
| | | const char* sql = |
| | | "SELECT COUNT(1) FROM alarms " |
| | | "WHERE start_time >= ? AND start_time < ?;"; |
| | | sqlite3_stmt* stmt = nullptr; |
| | | if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) == SQLITE_OK) { |
| | | sqlite3_bind_text(stmt, 1, win.startLocal.c_str(), -1, SQLITE_TRANSIENT); |
| | | sqlite3_bind_text(stmt, 2, win.endLocal.c_str(), -1, SQLITE_TRANSIENT); |
| | | if (sqlite3_step(stmt) == SQLITE_ROW) out.alarmsTriggered = sqlite3_column_int(stmt, 0); |
| | | sqlite3_finalize(stmt); |
| | | } |
| | | } |
| | | |
| | | // 2) overlapping (including active) |
| | | { |
| | | const char* sql = |
| | | "SELECT severity_level, start_time, end_time " |
| | | "FROM alarms " |
| | | "WHERE start_time < ? AND (end_time IS NULL OR end_time >= ?);"; |
| | | sqlite3_stmt* stmt = nullptr; |
| | | if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) == SQLITE_OK) { |
| | | sqlite3_bind_text(stmt, 1, win.endLocal.c_str(), -1, SQLITE_TRANSIENT); |
| | | sqlite3_bind_text(stmt, 2, win.startLocal.c_str(), -1, SQLITE_TRANSIENT); |
| | | |
| | | const auto now = std::chrono::system_clock::now(); |
| | | for (;;) { |
| | | const int rc = sqlite3_step(stmt); |
| | | if (rc == SQLITE_ROW) { |
| | | const int severity = sqlite3_column_int(stmt, 0); |
| | | const char* sStart = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)); |
| | | const char* sEnd = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2)); |
| | | std::chrono::system_clock::time_point aStart{}; |
| | | if (!TryParseLocalTime(sStart ? sStart : "", aStart)) continue; |
| | | std::chrono::system_clock::time_point aEnd{}; |
| | | bool hasEnd = TryParseLocalTime(sEnd ? sEnd : "", aEnd); |
| | | if (!hasEnd) aEnd = std::min(now, win.end); |
| | | |
| | | const auto clipStart = std::max(aStart, win.start); |
| | | const auto clipEnd = std::min(aEnd, win.end); |
| | | if (clipEnd > clipStart) { |
| | | const auto secs = std::chrono::duration_cast<std::chrono::seconds>(clipEnd - clipStart).count(); |
| | | out.downtimeMinutes += static_cast<double>(secs) / 60.0; |
| | | } |
| | | |
| | | out.bySeverity[severity] += 1; |
| | | out.alarmsOverlapping += 1; |
| | | } |
| | | else if (rc == SQLITE_DONE) { |
| | | break; |
| | | } |
| | | else { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | sqlite3_finalize(stmt); |
| | | } |
| | | } |
| | | |
| | | sqlite3_close(db); |
| | | } |
| | | |
| | | static void ComputeTransferSummaryFromDb( |
| | | const ProductionShiftWindow& win, |
| | | ProductionTransferSummary& out) |
| | | { |
| | | const std::string dbPath = PickDbPath("DB\\TransferManager.db", "DB\\TransferManager.db"); |
| | | sqlite3* db = nullptr; |
| | | if (sqlite3_open_v2(dbPath.c_str(), &db, SQLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX, nullptr) != SQLITE_OK) { |
| | | if (db) sqlite3_close(db); |
| | | return; |
| | | } |
| | | |
| | | const char* sql = |
| | | "SELECT status, create_time, end_time " |
| | | "FROM transfers " |
| | | "WHERE end_time >= ? AND end_time < ? AND end_time != '';"; |
| | | sqlite3_stmt* stmt = nullptr; |
| | | if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) { |
| | | sqlite3_close(db); |
| | | return; |
| | | } |
| | | |
| | | sqlite3_bind_text(stmt, 1, win.startLocal.c_str(), -1, SQLITE_TRANSIENT); |
| | | sqlite3_bind_text(stmt, 2, win.endLocal.c_str(), -1, SQLITE_TRANSIENT); |
| | | |
| | | long long totalSecs = 0; |
| | | long long cntSecs = 0; |
| | | |
| | | for (;;) { |
| | | const int rc = sqlite3_step(stmt); |
| | | if (rc == SQLITE_ROW) { |
| | | const char* sStatus = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)); |
| | | const char* sCreate = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)); |
| | | const char* sEnd = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2)); |
| | | |
| | | const std::string status = sStatus ? sStatus : ""; |
| | | out.byStatus[status] += 1; |
| | | out.transfersFinished += 1; |
| | | |
| | | std::chrono::system_clock::time_point tpCreate{}, tpEnd{}; |
| | | if (TryParseLocalTime(sCreate ? sCreate : "", tpCreate) && TryParseLocalTime(sEnd ? sEnd : "", tpEnd) && tpEnd > tpCreate) { |
| | | totalSecs += std::chrono::duration_cast<std::chrono::seconds>(tpEnd - tpCreate).count(); |
| | | cntSecs += 1; |
| | | } |
| | | } |
| | | else if (rc == SQLITE_DONE) { |
| | | break; |
| | | } |
| | | else { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | sqlite3_finalize(stmt); |
| | | sqlite3_close(db); |
| | | |
| | | out.avgCreateToEndSeconds = (cntSecs > 0) ? (static_cast<double>(totalSecs) / static_cast<double>(cntSecs)) : 0.0; |
| | | } |
| | | |
| | | bool ProductionStats::GetCurrentShiftWindow(CConfiguration& config, ProductionShiftWindow& outWindow) |
| | | { |
| | | int dayMin = 8 * 60; |
| | | int nightMin = 20 * 60; |
| | | config.getProductionShiftStartMinutes(dayMin, nightMin); |
| | | |
| | | const auto now = std::chrono::system_clock::now(); |
| | | const std::time_t ttNow = std::chrono::system_clock::to_time_t(now); |
| | | std::tm tmNow{}; |
| | | localtime_s(&tmNow, &ttNow); |
| | | std::tm tmMid = tmNow; |
| | | tmMid.tm_hour = 0; |
| | | tmMid.tm_min = 0; |
| | | tmMid.tm_sec = 0; |
| | | tmMid.tm_isdst = -1; |
| | | const std::time_t ttMid = mktime(&tmMid); |
| | | if (ttMid == (time_t)-1) return false; |
| | | |
| | | const auto midnight = std::chrono::system_clock::from_time_t(ttMid); |
| | | const auto startDayToday = midnight + std::chrono::minutes(dayMin); |
| | | const auto startNightToday = midnight + std::chrono::minutes(nightMin); |
| | | |
| | | const auto startDay = (now >= startDayToday) ? startDayToday : (startDayToday - std::chrono::hours(24)); |
| | | const auto startNight = (now >= startNightToday) ? startNightToday : (startNightToday - std::chrono::hours(24)); |
| | | |
| | | ProductionShiftType type = ProductionShiftType::Day; |
| | | auto start = startDay; |
| | | if (startNight > startDay) { |
| | | type = ProductionShiftType::Night; |
| | | start = startNight; |
| | | } |
| | | |
| | | const int durationMin = |
| | | (type == ProductionShiftType::Day) |
| | | ? ((nightMin - dayMin + 24 * 60) % (24 * 60)) |
| | | : ((dayMin - nightMin + 24 * 60) % (24 * 60)); |
| | | if (durationMin <= 0) return false; |
| | | |
| | | outWindow.type = type; |
| | | outWindow.start = start; |
| | | outWindow.end = start + std::chrono::minutes(durationMin); |
| | | outWindow.startLocal = FormatLocal(outWindow.start); |
| | | outWindow.endLocal = FormatLocal(outWindow.end); |
| | | outWindow.startUtcIso = FormatUtcIso(outWindow.start); |
| | | outWindow.endUtcIso = FormatUtcIso(outWindow.end); |
| | | return true; |
| | | } |
| | | |
| | | bool ProductionStats::ComputeCurrentShiftSummary(CConfiguration& config, ProductionShiftSummary& outSummary) |
| | | { |
| | | ProductionShiftWindow win; |
| | | if (!GetCurrentShiftWindow(config, win)) return false; |
| | | |
| | | outSummary = ProductionShiftSummary{}; |
| | | outSummary.window = win; |
| | | |
| | | ComputeOutputFromProcessDb(win, outSummary.output); |
| | | ComputeAlarmSummaryFromDb(win, outSummary.alarms); |
| | | ComputeTransferSummaryFromDb(win, outSummary.transfers); |
| | | return true; |
| | | } |
| | | |
| | | void ProductionStats::LogCurrentShiftSummary(CConfiguration& config) |
| | | { |
| | | ProductionShiftSummary s; |
| | | if (!ComputeCurrentShiftSummary(config, s)) { |
| | | LOGE("<ProductionStats>Failed to compute shift summary."); |
| | | return; |
| | | } |
| | | |
| | | const char* shiftName = (s.window.type == ProductionShiftType::Day) ? "Day" : "Night"; |
| | | LOGI("<ProductionStats>Shift=%s, [%s ~ %s]", shiftName, s.window.startLocal.c_str(), s.window.endLocal.c_str()); |
| | | LOGI("<ProductionStats>Output(pairs): total=%lld, pass=%lld, fail=%lld, no_result=%lld, yield=%.2f%%", |
| | | s.output.pairsTotal, s.output.pairsPass, s.output.pairsFail, s.output.pairsNoResult, s.output.yield * 100.0); |
| | | LOGI("<ProductionStats>Alarms: triggered=%d, overlapping=%d, downtime=%.1f min", |
| | | s.alarms.alarmsTriggered, s.alarms.alarmsOverlapping, s.alarms.downtimeMinutes); |
| | | if (!s.alarms.bySeverity.empty()) { |
| | | std::ostringstream oss; |
| | | oss << "<ProductionStats>AlarmsBySeverity:"; |
| | | for (const auto& kv : s.alarms.bySeverity) oss << " L" << kv.first << "=" << kv.second; |
| | | LOGI("%s", oss.str().c_str()); |
| | | } |
| | | LOGI("<ProductionStats>Transfers: finished=%d, avg(create->end)=%.1fs", s.transfers.transfersFinished, s.transfers.avgCreateToEndSeconds); |
| | | if (!s.transfers.byStatus.empty()) { |
| | | std::ostringstream oss; |
| | | oss << "<ProductionStats>TransfersByStatus:"; |
| | | for (const auto& kv : s.transfers.byStatus) oss << " " << kv.first << "=" << kv.second; |
| | | LOGI("%s", oss.str().c_str()); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | |
| | | #include <chrono> |
| | | #include <map> |
| | | #include <string> |
| | | |
| | | class CConfiguration; |
| | | |
| | | enum class ProductionShiftType : int { |
| | | Day = 1, |
| | | Night = 2 |
| | | }; |
| | | |
| | | struct ProductionShiftWindow { |
| | | ProductionShiftType type{ ProductionShiftType::Day }; |
| | | std::chrono::system_clock::time_point start{}; |
| | | std::chrono::system_clock::time_point end{}; |
| | | std::string startLocal; // "YYYY-MM-DD HH:MM:SS" |
| | | std::string endLocal; // "YYYY-MM-DD HH:MM:SS" |
| | | std::string startUtcIso; // "YYYY-MM-DDTHH:MM:SSZ" |
| | | std::string endUtcIso; // "YYYY-MM-DDTHH:MM:SSZ" |
| | | }; |
| | | |
| | | struct ProductionOutputSummary { |
| | | long long pairsTotal = 0; // "对æ°" |
| | | long long pairsPass = 0; |
| | | long long pairsFail = 0; |
| | | long long pairsNoResult = 0; |
| | | double yield = 0.0; // pairsPass / (pairsPass + pairsFail), 0 if denom==0 |
| | | }; |
| | | |
| | | struct ProductionAlarmSummary { |
| | | int alarmsTriggered = 0; // start_time within shift window |
| | | int alarmsOverlapping = 0; // overlaps shift window (including active) |
| | | double downtimeMinutes = 0.0; // overlap minutes (best-effort) |
| | | std::map<int, int> bySeverity; // severity_level -> count (overlapping) |
| | | }; |
| | | |
| | | struct ProductionTransferSummary { |
| | | int transfersFinished = 0; // end_time within shift window |
| | | std::map<std::string, int> byStatus; |
| | | double avgCreateToEndSeconds = 0.0; |
| | | }; |
| | | |
| | | struct ProductionShiftSummary { |
| | | ProductionShiftWindow window; |
| | | ProductionOutputSummary output; |
| | | ProductionAlarmSummary alarms; |
| | | ProductionTransferSummary transfers; |
| | | }; |
| | | |
| | | class ProductionStats { |
| | | public: |
| | | static bool GetCurrentShiftWindow(CConfiguration& config, ProductionShiftWindow& outWindow); |
| | | static bool ComputeCurrentShiftSummary(CConfiguration& config, ProductionShiftSummary& outSummary); |
| | | static void LogCurrentShiftSummary(CConfiguration& config); |
| | | }; |
| | | |
| | |
| | | |
| | | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) |
| | | LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED |
| | | #pragma code_page(936) |
| | | |
| | | #ifdef APSTUDIO_INVOKED |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | |
| | | LTEXT "åç§°ï¼",IDC_STATIC,12,32,50,8 |
| | | EDITTEXT IDC_EDIT_EVT_NAME,70,30,260,14,ES_AUTOHSCROLL |
| | | LTEXT "æè¿°ï¼",IDC_STATIC,12,52,50,8 |
| | | EDITTEXT IDC_EDIT_EVT_DESC,70,50,260,34,ES_AUTOHSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL |
| | | EDITTEXT IDC_EDIT_EVT_DESC,70,50,260,34,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_VSCROLL |
| | | LTEXT "éæ©Reportï¼",IDC_STATIC_SELECT_VARS,12,90,70,8 |
| | | CONTROL "",IDC_LIST_EVT_RPTS,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,12,100,316,90 |
| | | DEFPUSHBUTTON "ç¡®å®",IDOK,200,196,50,14 |
| | |
| | | DEFPUSHBUTTON "ç¡®å®",IDOK,283,238,50,14 |
| | | PUSHBUTTON "åæ¶",IDCANCEL,338,238,50,14 |
| | | CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,381,226 |
| | | END |
| | | |
| | | IDD_PANEL_PRODUCTION DIALOGEX 0, 0, 311, 254 |
| | | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU |
| | | FONT 8, "MS Shell Dlg", 400, 0, 0x1 |
| | | BEGIN |
| | | LTEXT "Test",IDC_STATIC,95,67,15,8 |
| | | CONTROL "Custom1",IDC_LINE1,"BYVerticalLine",WS_TABSTOP,286,7,18,240 |
| | | END |
| | | |
| | | |
| | |
| | | TOPMARGIN, 7 |
| | | BOTTOMMARGIN, 252 |
| | | END |
| | | |
| | | IDD_PANEL_PRODUCTION, DIALOG |
| | | BEGIN |
| | | LEFTMARGIN, 7 |
| | | RIGHTMARGIN, 304 |
| | | TOPMARGIN, 7 |
| | | BOTTOMMARGIN, 247 |
| | | END |
| | | END |
| | | #endif // APSTUDIO_INVOKED |
| | | |
| | |
| | | 0 |
| | | END |
| | | |
| | | IDD_PANEL_PRODUCTION AFX_DIALOG_LAYOUT |
| | | BEGIN |
| | | 0 |
| | | END |
| | | |
| | | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // |
| | |
| | | BEGIN |
| | | MENUITEM "æ¥å¿çªå£(&L)", ID_MENU_WND_LOG |
| | | MENUITEM "è¦åçªå£(A)", 32781 |
| | | MENUITEM SEPARATOR |
| | | MENUITEM "æµè¯é¢æ¿(T)", ID_MENU_WND_TEST_PANEL |
| | | MENUITEM "çäº§é¢æ¿(P)", ID_MENU_WND_PRO_PANEL |
| | | END |
| | | POPUP "帮å©(&H)" |
| | | BEGIN |
| | |
| | | <ClInclude Include="CPageLinkSignal.h" /> |
| | | <ClInclude Include="CPageReport.h" /> |
| | | <ClInclude Include="CPageVarialbles.h" /> |
| | | <ClInclude Include="CPanelProduction.h" /> |
| | | <ClInclude Include="ProductionStats.h" /> |
| | | <ClInclude Include="CParam.h" /> |
| | | <ClInclude Include="CCjPage1.h" /> |
| | | <ClInclude Include="CProcessDataListDlg.h" /> |
| | |
| | | <ClCompile Include="CPageLinkSignal.cpp" /> |
| | | <ClCompile Include="CPageReport.cpp" /> |
| | | <ClCompile Include="CPageVarialbles.cpp" /> |
| | | <ClCompile Include="ConfigurationProduction.cpp" /> |
| | | <ClCompile Include="CPanelProduction.cpp" /> |
| | | <ClCompile Include="ProductionStats.cpp" /> |
| | | <ClCompile Include="CParam.cpp" /> |
| | | <ClCompile Include="CCjPage1.cpp" /> |
| | | <ClCompile Include="CProcessDataListDlg.cpp" /> |
| | |
| | | <ClCompile Include="RecipeDeviceBindDlg.cpp" /> |
| | | <ClCompile Include="CCustomCheckBox.cpp" /> |
| | | <ClCompile Include="CCollectionEvent.cpp" /> |
| | | <ClCompile Include="CEventEditDlg.cpp"> |
| | | <Filter>Source Files</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="CReport.cpp" /> |
| | | <ClCompile Include="CReportEditDlg.cpp"> |
| | | <Filter>Source Files</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="CVariable.cpp" /> |
| | | <ClCompile Include="CPageVarialbles.cpp" /> |
| | | <ClCompile Include="CPageReport.cpp" /> |
| | |
| | | <ClCompile Include="CUserEdit2Dlg.cpp" /> |
| | | <ClCompile Include="CUserXLogDlg.cpp" /> |
| | | <ClCompile Include="CVariableEditDlg2.cpp" /> |
| | | <ClCompile Include="CEventEditDlg.cpp" /> |
| | | <ClCompile Include="CReportEditDlg.cpp" /> |
| | | <ClCompile Include="ConfigurationProduction.cpp" /> |
| | | <ClCompile Include="CPanelProduction.cpp" /> |
| | | <ClCompile Include="ProductionStats.cpp" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClInclude Include="AlarmManager.h" /> |
| | |
| | | <ClInclude Include="stdafx.h" /> |
| | | <ClInclude Include="targetver.h" /> |
| | | <ClInclude Include="TerminalDisplayDlg.h" /> |
| | | <ClInclude Include="ProductionStats.h" /> |
| | | <ClInclude Include="SECSRuntimeManager.h" /> |
| | | <ClInclude Include="CCLinkPerformance\CCLinkIEControl.h"> |
| | | <Filter>CCLinkPerformance</Filter> |
| | |
| | | <ClInclude Include="RecipeDeviceBindDlg.h" /> |
| | | <ClInclude Include="CCustomCheckBox.h" /> |
| | | <ClInclude Include="CCollectionEvent.h" /> |
| | | <ClInclude Include="CEventEditDlg.h"> |
| | | <Filter>Header Files</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="CReport.h" /> |
| | | <ClInclude Include="CReportEditDlg.h"> |
| | | <Filter>Header Files</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="CVariable.h" /> |
| | | <ClInclude Include="CPageVarialbles.h" /> |
| | | <ClInclude Include="CPageReport.h" /> |
| | |
| | | <ClInclude Include="CUserEdit2Dlg.h" /> |
| | | <ClInclude Include="CUserXLogDlg.h" /> |
| | | <ClInclude Include="CVariableEditDlg2.h" /> |
| | | <ClInclude Include="CEventEditDlg.h" /> |
| | | <ClInclude Include="CReportEditDlg.h" /> |
| | | <ClInclude Include="CPanelProduction.h" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="Servo.rc" /> |
| | |
| | | m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); |
| | | m_crBkgnd = APPDLG_BACKGROUND_COLOR; |
| | | m_hbrBkgnd = nullptr; |
| | | m_nLeftPanelType = 2; |
| | | m_pTerminalDisplayDlg = nullptr; |
| | | m_pObserver = nullptr; |
| | | m_pPanelMaster = nullptr; |
| | | m_pPanelProduction = nullptr; |
| | | m_pPanelEquipment = nullptr; |
| | | m_pPanelAttributes = nullptr; |
| | | m_pPageGraph1 = nullptr; |
| | |
| | | ON_UPDATE_COMMAND_UI(ID_MENU_TEST_MESSAGE_CLEAR, &CServoDlg::OnUpdateMenuTestMessageClear) |
| | | ON_COMMAND(ID_MENU_TOOLS_CLIENT_LIST, &CServoDlg::OnMenuToolsClientList) |
| | | ON_UPDATE_COMMAND_UI(ID_MENU_TOOLS_CLIENT_LIST, &CServoDlg::OnUpdateMenuToolsClientList) |
| | | ON_COMMAND(ID_MENU_WND_TEST_PANEL, &CServoDlg::OnMenuWndTestPanel) |
| | | ON_UPDATE_COMMAND_UI(ID_MENU_WND_TEST_PANEL, &CServoDlg::OnUpdateMenuWndTestPanel) |
| | | ON_COMMAND(ID_MENU_WND_PRO_PANEL, &CServoDlg::OnMenuWndProPanel) |
| | | ON_UPDATE_COMMAND_UI(ID_MENU_WND_PRO_PANEL, &CServoDlg::OnUpdateMenuWndProPanel) |
| | | ON_COMMAND(ID_MENU_HELP_ABOUT, &CServoDlg::OnMenuHelpAbout) |
| | | ON_WM_INITMENUPOPUP() |
| | | ON_WM_TIMER() |
| | |
| | | |
| | | if (STATE::NOT_CONNECTED == state) { |
| | | m_pMyStatusbar->setCimBtnText("Disconnected"); |
| | | //m_labelPassiveState.setBackground(DISCONNECTED_BACKGROUND); |
| | | //m_labelPassiveState.setForeground(DISCONNECTED_FOREGROUND, TRUE); |
| | | m_pMyStatusbar->setCimBtnColors( |
| | | CIM_STATUS_BK_DISCONNECTED, CIM_STATUS_BK_DISCONNECTED, RGB(0, 0, 0)); |
| | | } |
| | | else if (STATE::NOT_SELECTED == state) { |
| | | m_pMyStatusbar->setCimBtnText("Not Selected"); |
| | | //m_labelPassiveState.setBackground(NOT_SELECTED_BACKGROUND); |
| | | //m_labelPassiveState.setForeground(NOT_SELECTED_FOREGROUND, TRUE); |
| | | m_pMyStatusbar->setCimBtnColors( |
| | | CIM_STATUS_BK_DISCONNECTED, CIM_STATUS_BK_DISCONNECTED, RGB(0, 0, 0)); |
| | | } |
| | | else if (STATE::SELECTED == state) { |
| | | m_pMyStatusbar->setCimBtnText("Selected"); |
| | | //m_labelPassiveState.setBackground(SELECTED_BACKGROUND); |
| | | //m_labelPassiveState.setForeground(SELECTED_FOREGROUND, TRUE); |
| | | m_pMyStatusbar->setCimBtnColors( |
| | | CIM_STATUS_BK_SELECTED, CIM_STATUS_BK_SELECTED, RGB(0, 0, 0)); |
| | | } |
| | | } |
| | | pAny->release(); |
| | |
| | | m_pTab->SetBkgndColor(RGB(222, 222, 222)); |
| | | ShowChildPage(0); |
| | | |
| | | // 读å颿¿å®½ |
| | | CString strIniFile; |
| | | strIniFile.Format(_T("%s\\%s.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir, (LPTSTR)(LPCTSTR)theApp.m_strAppFile); |
| | | int nPanelWidth = GetPrivateProfileInt(_T("App"), _T("MasterPanelWidth"), |
| | | int((double)GetSystemMetrics(SM_CXSCREEN) * 0.25), (LPTSTR)(LPCTSTR)strIniFile); |
| | | |
| | | m_pPanelMaster = new CPanelMaster(); |
| | | m_pPanelMaster->setPanelWidth(nPanelWidth); |
| | | m_pPanelMaster->Create(IDD_PANEL_MASTER, this); |
| | | m_pPanelMaster->ShowWindow(SW_SHOW); |
| | | m_pPanelProduction = new CPanelProduction(); |
| | | m_pPanelProduction->setPanelWidth(nPanelWidth); |
| | | m_pPanelProduction->Create(IDD_PANEL_PRODUCTION, this); |
| | | SetLeftPanelType(m_nLeftPanelType, false); |
| | | m_pPanelEquipment = new CPanelEquipment(); |
| | | m_pPanelEquipment->Create(IDD_PANEL_EQUIPMENT, this); |
| | | m_pPanelAttributes = new CPanelAttributes(); |
| | |
| | | pCmdUI->Enable(TRUE); |
| | | } |
| | | |
| | | void CServoDlg::OnMenuWndTestPanel() |
| | | { |
| | | SetLeftPanelType(1); |
| | | } |
| | | |
| | | void CServoDlg::OnUpdateMenuWndTestPanel(CCmdUI* pCmdUI) |
| | | { |
| | | pCmdUI->Enable(TRUE); |
| | | pCmdUI->SetCheck(m_nLeftPanelType == 1); |
| | | } |
| | | |
| | | void CServoDlg::OnMenuWndProPanel() |
| | | { |
| | | SetLeftPanelType(2); |
| | | } |
| | | |
| | | void CServoDlg::OnUpdateMenuWndProPanel(CCmdUI* pCmdUI) |
| | | { |
| | | pCmdUI->Enable(TRUE); |
| | | pCmdUI->SetCheck(m_nLeftPanelType == 2); |
| | | } |
| | | |
| | | void CServoDlg::OnMenuHelpAbout() |
| | | { |
| | | theApp.m_model.getMaster().test(); |
| | |
| | | m_pPanelMaster->DestroyWindow(); |
| | | delete m_pPanelMaster; |
| | | m_pPanelMaster = nullptr; |
| | | } |
| | | |
| | | if (m_pPanelProduction != nullptr) { |
| | | m_pPanelProduction->DestroyWindow(); |
| | | delete m_pPanelProduction; |
| | | m_pPanelProduction = nullptr; |
| | | } |
| | | |
| | | if (m_pPanelEquipment != nullptr) { |
| | |
| | | |
| | | |
| | | int nPanelWidth = 0; |
| | | if (m_pPanelMaster != nullptr) { |
| | | if (m_pPanelMaster != nullptr && ::IsWindow(m_pPanelMaster->GetSafeHwnd()) |
| | | && m_pPanelMaster->IsWindowVisible()) { |
| | | nPanelWidth = m_pPanelMaster->getPanelWidth(); |
| | | m_pPanelMaster->MoveWindow(x, y, nPanelWidth, y2 - y); |
| | | x += nPanelWidth; |
| | | } |
| | | |
| | | if (m_pPanelProduction != nullptr && m_pPanelProduction->IsWindowVisible()) { |
| | | nPanelWidth = m_pPanelProduction->getPanelWidth(); |
| | | m_pPanelProduction->MoveWindow(x, y, nPanelWidth, y2 - y); |
| | | x += nPanelWidth; |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | m_pMyStatusbar->MoveWindow(0, y2, rcClient.Width(), STATUSBAR_HEIGHT); |
| | | } |
| | | |
| | | void CServoDlg::SetLeftPanelType(int type, bool resize) |
| | | { |
| | | if (type != 1 && type != 2) { |
| | | type = 1; |
| | | } |
| | | |
| | | m_nLeftPanelType = type; |
| | | if (m_pPanelMaster != nullptr) { |
| | | m_pPanelMaster->ShowWindow(SW_HIDE); |
| | | } |
| | | if (m_pPanelProduction != nullptr) { |
| | | m_pPanelProduction->ShowWindow(SW_HIDE); |
| | | } |
| | | if (type == 1 && m_pPanelMaster != nullptr) { |
| | | m_pPanelMaster->ShowWindow(SW_SHOW); |
| | | } |
| | | else if (type == 2 && m_pPanelProduction != nullptr) { |
| | | m_pPanelProduction->ShowWindow(SW_SHOW); |
| | | } |
| | | |
| | | if (resize && ::IsWindow(m_hWnd)) { |
| | | Resize(); |
| | | DrawMenuBar(); |
| | | } |
| | | } |
| | | |
| | | void CServoDlg::OnClose() |
| | |
| | | LRESULT CServoDlg::OnPanelResize(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | int width = (int)wParam; |
| | | // m_pPanel->SetPanelWidth(width); |
| | | |
| | | if (m_pPanelMaster != nullptr) { |
| | | m_pPanelMaster->setPanelWidth(width); |
| | | } |
| | | if (m_pPanelProduction != nullptr) { |
| | | m_pPanelProduction->setPanelWidth(width); |
| | | } |
| | | |
| | | CString strIniFile, strValue; |
| | | strIniFile.Format(_T("%s\\%s.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir, (LPTSTR)(LPCTSTR)theApp.m_strAppFile); |
| | | strValue.Format(_T("%d"), width); |
| | | WritePrivateProfileString(_T("App"), _T("MasterPanelWidth"), |
| | | (LPTSTR)(LPCTSTR)strValue, (LPTSTR)(LPCTSTR)strIniFile); |
| | | |
| | | Resize(); |
| | | |
| | | return 0; |
| | |
| | | } |
| | | |
| | | return strText; |
| | | } |
| | | } |
| | |
| | | #include "CPanelMaster.h" |
| | | #include "CPanelEquipment.h" |
| | | #include "CPanelAttributes.h" |
| | | #include "CPanelProduction.h" |
| | | #include "CPageGraph1.h" |
| | | #include "CPageGraph2.h" |
| | | #include "TopToolbar.h" |
| | |
| | | private: |
| | | void InitRxWindows(); |
| | | void Resize(); |
| | | void SetLeftPanelType(int type, bool resize = true); |
| | | void ShowChildPage(int index); |
| | | void UpdateLoginStatus(); |
| | | CString& GetRuntimeFormatText(CString& strText, const char* pszSuffix); |
| | |
| | | HICON m_hIcon; |
| | | COLORREF m_crBkgnd; |
| | | HBRUSH m_hbrBkgnd; |
| | | int m_nLeftPanelType; // 1: CPanelMaster, 2: CPanelProduction |
| | | CTopToolbar* m_pTopToolbar; |
| | | CPanelMaster* m_pPanelMaster; |
| | | CPanelProduction* m_pPanelProduction; |
| | | CPanelEquipment* m_pPanelEquipment; |
| | | CPanelAttributes* m_pPanelAttributes; |
| | | CMyStatusbar* m_pMyStatusbar; |
| | |
| | | afx_msg void OnUpdateMenuTestMessageClear(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuToolsClientList(); |
| | | afx_msg void OnUpdateMenuToolsClientList(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuWndTestPanel(); |
| | | afx_msg void OnUpdateMenuWndTestPanel(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuWndProPanel(); |
| | | afx_msg void OnUpdateMenuWndProPanel(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuHelpAbout(); |
| | | afx_msg void OnTimer(UINT_PTR nIDEvent); |
| | | afx_msg LRESULT OnPanelResize(WPARAM wParam, LPARAM lParam); |
| | |
| | | #define IDD_DIALOG_CLIENT_LIST 162 |
| | | #define IDD_DIALOG_LOGIN 163 |
| | | #define IDD_DIALOG_INPUT 164 |
| | | #define IDD_DIALOG_VARIABLE_EDIT2 186 |
| | | #define IDD_DIALOG_REPORT_EDIT 187 |
| | | #define IDD_DIALOG_EVENT_EDIT 188 |
| | | #define IDD_PAGE_LINK_SIGNAL 165 |
| | | #define IDD_DIALOG_SYSTEM_LOG_MANAGER 166 |
| | | #define IDD_DIALOG_RECIPE_DEVICE_BIND 167 |
| | |
| | | #define IDD_DIALOG_USER_EDIT2 182 |
| | | #define IDD_DIALOG1 184 |
| | | #define IDD_DIALOG_USERX_LOG 184 |
| | | #define IDD_DIALOG_VARIABLE_EDIT2 186 |
| | | #define IDD_DIALOG_REPORT_EDIT 187 |
| | | #define IDD_DIALOG_EVENT_EDIT 188 |
| | | #define IDD_PANEL_PRODUCTION 189 |
| | | #define IDC_SERVO_GRAPH1 1001 |
| | | #define IDC_BUTTON_LOG 1002 |
| | | #define IDC_EDIT_LOG 1003 |
| | |
| | | #define IDC_EDIT_USER_PASSWORD 1232 |
| | | #define IDC_COMBO_USER_ROLE 1233 |
| | | #define IDC_CHECK_USER_ENABLED 1234 |
| | | #define IDC_LIST_RPT_VARS 1241 |
| | | #define IDC_STATIC_SELECT_VARS 1242 |
| | | #define IDC_EDIT_VAR_ID 1235 |
| | | #define IDC_COMBO_VAR_TYPE 1236 |
| | | #define IDC_EDIT_VAR_NAME 1237 |
| | | #define IDC_EDIT_VAR_REMARK 1238 |
| | | #define IDC_EDIT_RPT_ID 1239 |
| | | #define IDC_EDIT_RPT_VIDS 1240 |
| | | #define IDC_LIST_RPT_VARS 1241 |
| | | #define IDC_STATIC_SELECT_VARS 1242 |
| | | #define IDC_EDIT_EVT_ID 1243 |
| | | #define IDC_EDIT_EVT_NAME 1244 |
| | | #define IDC_EDIT_EVT_DESC 1245 |
| | | #define IDC_LIST_EVT_RPTS 1246 |
| | | #define IDC_EDIT_VAR_ID 1235 |
| | | #define IDC_COMBO_VAR_TYPE 1236 |
| | | #define IDC_EDIT_VAR_NAME 1237 |
| | | #define ID_MENU_HELP_ABOUT 32771 |
| | | #define ID_MENU_FILE_EXIT 32772 |
| | | #define ID_MENU_FILE_SECSTEST 32773 |
| | |
| | | #define ID_EQSGRAPHITEM_TEST6 32798 |
| | | #define ID_MENU_PROJECT_VARIABLE_LIST 32800 |
| | | #define ID_MENU_TOOLS_CLIENT_LIST 32801 |
| | | #define ID_MENU_WND_TEST_PANEL 32802 |
| | | #define ID_MENU_WND_PRO_PANEL 32803 |
| | | |
| | | // Next default values for new objects |
| | | // |
| | | #ifdef APSTUDIO_INVOKED |
| | | #ifndef APSTUDIO_READONLY_SYMBOLS |
| | | #define _APS_NEXT_RESOURCE_VALUE 189 |
| | | #define _APS_NEXT_COMMAND_VALUE 32802 |
| | | #define _APS_NEXT_RESOURCE_VALUE 191 |
| | | #define _APS_NEXT_COMMAND_VALUE 32804 |
| | | #define _APS_NEXT_CONTROL_VALUE 1247 |
| | | #define _APS_NEXT_SYMED_VALUE 101 |
| | | #endif |
| | |
| | | 10051,CarrierIDWaitingForHost,,(10051) |
| | | 10052,CarrierIDVerificationOK,,(10052) |
| | | 10053,CarrierIDVerificationNG,,(10052) |
| | | 10061,SlotMapWaitingForHost,,(10061) |
| | | 10061,CheckSlotMap,,(10061) |
| | | 10062,SlotMapVerificationOK,,(10062) |
| | | 10063,SlotMapVerificationNG,,(10062) |
| | | 10071,GlassIDReadWaitingForHost,,(10071) |
| | |
| | | 50008,Port_Unload_Ready,,(50008) |
| | | 50009,Port_Load_Ready,,(50009) |
| | | 50010,Port_Blocked,,(50010) |
| | | 50011,TestEvent,TestEvent,æµè¯ä¸ä¸,(50011) |
| | | 50011,OCR_PanelID_Read_OK,æ«ç äºä»¶ä¸æ¥,(50012) |
| | | 50012,Port_Ready_To_Release,,(50013) |
| | |
| | | 50009,(5011) |
| | | 50010,(5012) |
| | | 50011,(5013) |
| | | 50012,(5014) |
| | | 50013,(5015) |
| | |
| | | 5011,LoadReadyPortId,U1,"Port ID" |
| | | 5012,BlockedPortId,U1,"Port ID" |
| | | 5013,TestVID,U1,æµè¯æ·»å åé55 |
| | | 5014,VCRPanelID,A20,Panel id,æ¥èªè¯»ç å¨ |
| | | 5015,ReadyToReleasePortId,U1,"Port ID" |
| | | 10200,SlotMap,U2,SlotMap(Scan) |
| | | 10201,SlotMapScan,U2,SlotMap(Scan) |
| | | 10202,SlotMapDownload,U2,SlotMap(Download) |