Merge branch 'clh' into liuyang
| | |
| | | SourceCode/Bond/x64/Debug/HsmsPassive.cache |
| | | SourceCode/Bond/x64/Debug/MasterState.dat |
| | | SourceCode/Bond/x64/Debug/Recipe/EQ10_Unit0.recipelist |
| | | SourceCode/Bond/UserX/ |
| | | Document/~$Panel Bonderå
«é¶èå SecsTest CheckList_v3.0.xlsx |
| | |
| | | SVID,SV Name,SV Format,SV Remark |
| | | 100,PortTransferState,U1,"0=OutOfService\r\n1=TransferBlocked\r\n2=ReadyToLoad\r\n3=ReadyToUnload\r\n4=InService\r\n5=TransferReady" |
| | | 300,AccessMode,U1,"1=Manual\r\n2=Auto" |
| | | 10000,CarrierID_P1,A50,Carrier ID for Port 1 |
| | | 10001,CarrierID_P2,A50,Carrier ID for Port 2 |
| | | 10002,CarrierID_P3,A50,Carrier ID for Port 3 |
| | | 10003,CarrierID_P4,A50,Carrier ID for Port 4 |
| | | 100,PortTransferState_P1,U1,1=LoadReady;2=Loaded;3=InUse;4=UnloadReady;5=Empty;6=Blocked |
| | | 101,PortTransferState_P2,U1,1=LoadReady;2=Loaded;3=InUse;4=UnloadReady;5=Empty;6=Blocked |
| | | 102,PortTransferState_P3,U1,1=LoadReady;2=Loaded;3=InUse;4=UnloadReady;5=Empty;6=Blocked |
| | | 103,PortTransferState_P4,U1,1=LoadReady;2=Loaded;3=InUse;4=UnloadReady;5=Empty;6=Blocked |
| | | 300,AccessMode_P1,U1,0=OutOfService;1=TransferBlocked;2=ReadyToLoad;3=ReadyToUnload;4=InService;5=TransferReady |
| | | 301,AccessMode_P2,U1,0=OutOfService;1=TransferBlocked;2=ReadyToLoad;3=ReadyToUnload;4=InService;5=TransferReady |
| | | 302,AccessMode_P3,U1,0=OutOfService;1=TransferBlocked;2=ReadyToLoad;3=ReadyToUnload;4=InService;5=TransferReady |
| | | 303,AccessMode_P4,U1,0=OutOfService;1=TransferBlocked;2=ReadyToLoad;3=ReadyToUnload;4=InService;5=TransferReady |
| | | 500,Clock,A50, |
| | | 600,CurrentControlState,U1,"0:Offline:equipment\r\n1:Offline-Attempt\r\n2:Online\r\n3:Offline:host\r\n4:Online:Local\r\n5:Online:Remote" |
| | | 601,PreviousControlState,U1, |
| | |
| | | #if !defined(AFX_BLLABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_) |
| | | #if !defined(AFX_BLLABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_) |
| | | #define AFX_BLLABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_ |
| | | |
| | | #if _MSC_VER >= 1000 |
| | |
| | | |
| | | BOOL CAccordionWnd::RegisterWndClass() |
| | | { |
| | | WNDCLASS wc; |
| | | WNDCLASS wcExisting = {}; |
| | | HINSTANCE hInstance = AfxGetInstanceHandle(); |
| | | if (::GetClassInfo(hInstance, ACCORDIONWND_CLASS, &wcExisting) || |
| | | ::GetClassInfo(NULL, ACCORDIONWND_CLASS, &wcExisting)) { |
| | | return TRUE; |
| | | } |
| | | |
| | | WNDCLASS wc = {}; |
| | | wc.lpszClassName = ACCORDIONWND_CLASS; |
| | | wc.hInstance = AfxGetInstanceHandle(); |
| | | wc.hInstance = hInstance; |
| | | wc.lpfnWndProc = WindowProc; |
| | | wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); |
| | | wc.hIcon = 0; |
| | |
| | | wc.cbWndExtra = 0; |
| | | |
| | | // 注åèªå®ä¹ç±» |
| | | return (::RegisterClass(&wc) != 0); |
| | | if (::RegisterClass(&wc) != 0) { |
| | | return TRUE; |
| | | } |
| | | return (::GetLastError() == ERROR_CLASS_ALREADY_EXISTS); |
| | | } |
| | | |
| | | CAccordionWnd * CAccordionWnd::FromHandle(HWND hWnd) |
| | |
| | | <PropertyGroup Label="Globals"> |
| | | <ProjectGuid>{7864134E-C538-4C0F-AF24-215FFCCBBAB4}</ProjectGuid> |
| | | <RootNamespace>BondServo</RootNamespace> |
| | | <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> |
| | | <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion> |
| | | <Keyword>MFCProj</Keyword> |
| | | </PropertyGroup> |
| | | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
| | |
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> |
| | | <ConfigurationType>Application</ConfigurationType> |
| | | <UseDebugLibraries>true</UseDebugLibraries> |
| | | <PlatformToolset>v140</PlatformToolset> |
| | | <PlatformToolset>v142</PlatformToolset> |
| | | <CharacterSet>MultiByte</CharacterSet> |
| | | <UseOfMfc>Dynamic</UseOfMfc> |
| | | </PropertyGroup> |
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> |
| | | <ConfigurationType>Application</ConfigurationType> |
| | | <UseDebugLibraries>false</UseDebugLibraries> |
| | | <PlatformToolset>v140</PlatformToolset> |
| | | <PlatformToolset>v142</PlatformToolset> |
| | | <WholeProgramOptimization>true</WholeProgramOptimization> |
| | | <CharacterSet>MultiByte</CharacterSet> |
| | | <UseOfMfc>Dynamic</UseOfMfc> |
| | |
| | | #include "pch.h" |
| | | #include "pch.h" |
| | | #include "CHsmsActive.h" |
| | | #include "Log.h" |
| | | |
| | | |
| | | static unsigned int DATAID = 1; |
| | | static unsigned short DATAID = 1; |
| | | |
| | | // Truncated SECS message logging to avoid overly long strings crashing UI/log |
| | | static void LogSecsMessageBrief(const char* tag, IMessage* pMessage, size_t maxLen = 1024) |
| | | { |
| | | if (pMessage == nullptr) return; |
| | | const char* msgStr = pMessage->toString(); |
| | | if (msgStr == nullptr) return; |
| | | std::string buf(msgStr); |
| | | if (buf.size() > maxLen) { |
| | | buf = buf.substr(0, maxLen) + "...<truncated>"; |
| | | } |
| | | LOGI("%s%s", tag, buf.c_str()); |
| | | } |
| | | |
| | | CHsmsActive::CHsmsActive() |
| | | { |
| | |
| | | HEADER* pHeader = pMessage->getHeader(); |
| | | int nStream = (pHeader->stream & 0x7F); |
| | | |
| | | TRACE("æ¶å°æ¶æ¯ S%dF%d================\n", pHeader->stream & 0x7F, pHeader->function); |
| | | TRACE("Body:%s\n", pMessage->toString()); |
| | | LOGI("onRecvDataMessage(%s).", pMessage->toString()); |
| | | TRACE("æ¶å°æ¶æ¯ S%dF%d================\n", pHeader->stream & 0x7F, pHeader->function); |
| | | LogSecsMessageBrief("Body:", pMessage); |
| | | LogSecsMessageBrief("onRecvDataMessage:", pMessage); |
| | | |
| | | if (nStream == 5 && pHeader->function == 1) { |
| | | // S5F1 |
| | |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsRequestOnline() |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 17, ++m_nSystemByte); |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsRequestOffline() |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 15, ++m_nSystemByte); |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsGoLocal() |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 2 | REPLY, 41, ++m_nSystemByte); |
| | | ISECS2Item* pBody = pMessage->getBody(); |
| | | pBody->addItem("GoLocal", "RCMD"); |
| | | pBody->addItem(); // L: empty params |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsGoRemote() |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 2 | REPLY, 41, ++m_nSystemByte); |
| | | ISECS2Item* pBody = pMessage->getBody(); |
| | | pBody->addItem("GoRemote", "RCMD"); |
| | | pBody->addItem(); // L: empty params |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 3, ++m_nSystemByte); |
| | | |
| | | pMessage->getBody()->addU4Item(SVID, "SVID"); |
| | | pMessage->getBody()->addU2Item(static_cast<unsigned short>(SVID), "SVID"); |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsQueryAllStatusVariables() |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 11, ++m_nSystemByte); |
| | | // Host sends L:0 (empty list) to request all SVIDs. |
| | | pMessage->getBody()->addItem(); // empty list |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsQueryAllDataVariables() |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 21, ++m_nSystemByte); |
| | | // Host sends L:0 (empty list) to request all DVIDs. |
| | | pMessage->getBody()->addItem(); // empty list |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsQueryAllCollectionEvents() |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 23, ++m_nSystemByte); |
| | | // Host sends L:0 (empty list) to request all CEIDs. |
| | | pMessage->getBody()->addItem(); // empty list |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsEquipmentConstantRequest(const std::vector<unsigned short>& ecids) |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 2 | REPLY, 13, ++m_nSystemByte); |
| | | for (auto id : ecids) { |
| | | pMessage->getBody()->addU2Item(id, "ECID"); |
| | | } |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsEquipmentConstantSend(const std::vector<std::pair<unsigned short, std::string>>& ecidValues) |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 2 | REPLY, 15, ++m_nSystemByte); |
| | | ISECS2Item* pBody = pMessage->getBody(); |
| | | for (const auto& kv : ecidValues) { |
| | | ISECS2Item* pEntry = pBody->addItem(); |
| | | pEntry->addU2Item(kv.first, "ECID"); |
| | | pEntry->addItem(kv.second.c_str(), "ECV"); |
| | | } |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsDeletePPID(const std::vector<std::string>& ppids) |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 7 | REPLY, 17, ++m_nSystemByte); |
| | | if (nRet != 0 || pMessage == nullptr) return -1; |
| | | ISECS2Item* pBody = pMessage->getBody(); |
| | | for (const auto& ppid : ppids) { |
| | | pBody->addItem(ppid.c_str(), "PPID"); |
| | | } |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsProcessProgramRequest(const char* pszPPID) |
| | | { |
| | | if (pszPPID == nullptr || strlen(pszPPID) == 0) return -1; |
| | | IMessage* pMessage = nullptr; |
| | | if (HSMS_Create1Message(pMessage, m_nSessionId, 7 | REPLY, 5, ++m_nSystemByte) != 0 || pMessage == nullptr) { |
| | | return -1; |
| | | } |
| | | pMessage->getBody()->setString(pszPPID, "PPID"); |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | return hsmsCarrierActionRequest(DATAID, "CarrierRelease", pszCarrierId, PTN); |
| | | } |
| | | |
| | | int CHsmsActive::hsmsProceedWithSlotMap(unsigned int DATAID, |
| | | const char* pszCarrierId, |
| | | unsigned char PTN, |
| | | const char* pszLotId, |
| | | const std::vector<std::string>& panelIds, |
| | | const std::vector<unsigned char>& slotMap) |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 3 | REPLY, 17, ++m_nSystemByte); |
| | | if (nRet != 0 || pMessage == nullptr) { |
| | | return nRet; |
| | | } |
| | | |
| | | pMessage->getBody()->addU4Item(DATAID, "DATAID"); |
| | | pMessage->getBody()->addItem("ProceedWithSlotMap", "CARRIERACTION"); |
| | | pMessage->getBody()->addItem(pszCarrierId, "CARRIERID"); |
| | | pMessage->getBody()->addU1Item(PTN, "PTN"); |
| | | |
| | | // Extended params (currently not parsed by Servo side): { LOTID, PANELID_LIST, SLOTMAP_LIST } |
| | | ISECS2Item* pParams = pMessage->getBody()->addItem(); // L |
| | | pParams->addItem(pszLotId != nullptr ? pszLotId : "", "LOTID"); |
| | | |
| | | ISECS2Item* pPanelList = pParams->addItem(); // L |
| | | for (const auto& id : panelIds) { |
| | | pPanelList->addItem(id.c_str(), "PANELID"); |
| | | } |
| | | |
| | | ISECS2Item* pSlotMapList = pParams->addItem(); // L |
| | | for (auto v : slotMap) { |
| | | pSlotMapList->addU1Item(v, "SLOTSTATE"); |
| | | } |
| | | |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::hsmsPRJobMultiCreate(std::vector<SERVO::CProcessJob*>& pjs) |
| | | { |
| | | IMessage* pMessage = nullptr; |
| | | int nRet = HSMS_Create1Message(pMessage, m_nSessionId, 16 | REPLY, 15, ++m_nSystemByte); |
| | | char szMF[32] = {14}; |
| | | pMessage->getBody()->addU4Item(++DATAID, "DATAID"); |
| | | pMessage->getBody()->addU2Item(++DATAID, "DATAID"); |
| | | auto itemPjs = pMessage->getBody()->addItem(); |
| | | for (auto pj : pjs) { |
| | | auto itemPj = itemPjs->addItem(); |
| | |
| | | return 0; |
| | | } |
| | | |
| | | // éç¨çreply ack彿° |
| | | // éç¨çreply ack彿° |
| | | void CHsmsActive::replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName) |
| | | { |
| | | IMessage* pMessage = NULL; |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include <string> |
| | | #include <vector> |
| | | #include <map> |
| | |
| | | #include "ProcessJob.h" |
| | | |
| | | |
| | | #define SVID_ControlState 600 |
| | | #define SVID_CurrentProcessState 700 |
| | | #define SVID_CJobSpace 5001 |
| | | #define SVID_PJobSpace 5002 |
| | | #define SVID_PJobQueued 5003 |
| | | #define SVID_EQPPExecName 801 |
| | | #define SVID_Bonder1CurrentRecipe 8100 |
| | | #define SVID_Bonder2CurrentRecipe 8101 |
| | | #define SVID_VacuumBakeCurrentRecipe 8102 |
| | | #define SVID_BakeCoolingCurrentRecipe 8103 |
| | | #define SVID_MeasurementCurrentRecipe 8104 |
| | | #define SVID_EFEMCurrentRecipe 8105 |
| | | |
| | | |
| | | typedef std::function<void(void* pFrom, ACTIVESTATE state)> STATECHANGED; |
| | |
| | | // Deselect Request |
| | | int hsmsDeselectRequest(); |
| | | |
| | | // 建ç«é讯(S1F13) |
| | | // 建ç«é讯(S1F13) |
| | | int hsmsEstablishCommunications(); |
| | | |
| | | // Are You There |
| | | int hsmsAreYouThere(); |
| | | |
| | | // ControlState: Request Online/Offline (S1F17 / S1F15) |
| | | int hsmsRequestOnline(); |
| | | int hsmsRequestOffline(); |
| | | |
| | | // ControlState: GoLocal/GoRemote (S2F41) |
| | | int hsmsGoLocal(); |
| | | int hsmsGoRemote(); |
| | | |
| | | // Date time sync |
| | | int hsmsDatetimeSync(); |
| | |
| | | // Configure Spooling |
| | | int hsmsConfigureSpooling(std::map<unsigned int, std::set<unsigned int>>& spoolingConfig); |
| | | |
| | | // åéææ¸
空ç¼åçæ¶æ¯ |
| | | // åéææ¸
空ç¼åçæ¶æ¯ |
| | | int hsmsTransmitSpooledData(); |
| | | int hsmsPurgeSpooledData(); |
| | | |
| | | // æ¥è¯¢åé |
| | | // æ¥è¯¢åé |
| | | int hsmsSelectedEquipmentStatusRequest(unsigned int SVID); |
| | | int hsmsQueryAllStatusVariables(); // S1F11 |
| | | int hsmsQueryAllDataVariables(); // S1F21 |
| | | int hsmsQueryAllCollectionEvents(); // S1F23 |
| | | int hsmsEquipmentConstantRequest(const std::vector<unsigned short>& ecids); // S2F13 |
| | | int hsmsEquipmentConstantSend(const std::vector<std::pair<unsigned short, std::string>>& ecidValues); // S2F15 |
| | | |
| | | // æ¥è¯¢PPID List |
| | | // æ¥è¯¢PPID List |
| | | int hsmsQueryPPIDList(); |
| | | int hsmsDeletePPID(const std::vector<std::string>& ppids); // S7F17 |
| | | int hsmsProcessProgramRequest(const char* pszPPID); // S7F5 |
| | | |
| | | // S3F17 |
| | | // å¡å£å¨ä½è¯·æ± |
| | | // å¡å£å¨ä½è¯·æ± |
| | | int hsmsCarrierActionRequest(unsigned int DATAID, |
| | | const char* pszCarrierAction, |
| | | const char* pszCarrierId, |
| | |
| | | int hsmsProceedWithCarrier(unsigned int DATAID, |
| | | const char* pszCarrierId, |
| | | unsigned char PTN); |
| | | int CHsmsActive::hsmsCarrierRelease(unsigned int DATAID, |
| | | int hsmsProceedWithSlotMap(unsigned int DATAID, |
| | | const char* pszCarrierId, |
| | | unsigned char PTN, |
| | | const char* pszLotId, |
| | | const std::vector<std::string>& panelIds, |
| | | const std::vector<unsigned char>& slotMap); |
| | | int hsmsCarrierRelease(unsigned int DATAID, |
| | | const char* pszCarrierId, |
| | | unsigned char PTN); |
| | | |
| | |
| | | // S14F9 |
| | | int hsmsCreateControlJob(const char* pszControlJobId, std::vector<std::string>& processJobIds); |
| | | |
| | | // éè¿çreply彿° |
| | | // éè¿çreply彿° |
| | | void replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName); |
| | | |
| | | // reply ack0 |
| | |
| | | { |
| | | SERVO::CProcessJob* pj = new SERVO::CProcessJob("PJ0001"); |
| | | std::vector<uint8_t> slots1{ 1, 2, 3 }; |
| | | pj->addCarrier("CID1001", slots1); |
| | | pj->addCarrier("Test-Cassette-001", slots1); |
| | | pj->setRecipe(SERVO::RecipeMethod::NoTuning, "P1001"); |
| | | m_pjs.push_back(pj); |
| | | } |
| | |
| | | #include "afxdialogex.h" |
| | | #include "Common.h" |
| | | #include <regex> |
| | | #include <string> |
| | | #include <vector> |
| | | #include "CTerminalDisplayDlg.h" |
| | | #include "CEDEventReportDlg.h" |
| | | #include "CDefineReportsDlg.h" |
| | |
| | | ON_BN_CLICKED(IDC_BUTTON_TRANSMIT_SPOOLED_DATA, &CEAPSimulatorDlg::OnBnClickedButtonTransmitSpooledData) |
| | | ON_BN_CLICKED(IDC_BUTTON_PURGE_SPOOLED_DATA, &CEAPSimulatorDlg::OnBnClickedButtonPurgeSpooledData) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_PPID_LIST, &CEAPSimulatorDlg::OnBnClickedButtonQueryPpidList) |
| | | ON_BN_CLICKED(IDC_BUTTON_DELETE_PPID, &CEAPSimulatorDlg::OnBnClickedButtonDeletePpid) |
| | | ON_BN_CLICKED(IDC_BUTTON_PROCEED_WITH_CARRIER, &CEAPSimulatorDlg::OnBnClickedButtonProceedWithCarrier) |
| | | ON_BN_CLICKED(IDC_BUTTON_PROCEED_WITH_SLOTMAP, &CEAPSimulatorDlg::OnBnClickedButtonProceedWithSlotMap) |
| | | ON_BN_CLICKED(IDC_BUTTON_CARRIER_RELEASE, &CEAPSimulatorDlg::OnBnClickedButtonCarrierRelease) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_CJ_SPACE, &CEAPSimulatorDlg::OnBnClickedButtonQueryCjSpace) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_PJ_SPACE, &CEAPSimulatorDlg::OnBnClickedButtonQueryPjSpace) |
| | | ON_BN_CLICKED(IDC_BUTTON_CREATE_PJ, &CEAPSimulatorDlg::OnBnClickedButtonCreatePj) |
| | | ON_BN_CLICKED(IDC_BUTTON_CREATE_CJ, &CEAPSimulatorDlg::OnBnClickedButtonCreateCj) |
| | | ON_BN_CLICKED(IDC_BUTTON_CTRL_OFFLINE, &CEAPSimulatorDlg::OnBnClickedButtonCtrlOffline) |
| | | ON_BN_CLICKED(IDC_BUTTON_CTRL_ONLINE_LOCAL, &CEAPSimulatorDlg::OnBnClickedButtonCtrlOnlineLocal) |
| | | ON_BN_CLICKED(IDC_BUTTON_CTRL_ONLINE_REMOTE, &CEAPSimulatorDlg::OnBnClickedButtonCtrlOnlineRemote) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_CONTROL_STATE, &CEAPSimulatorDlg::OnBnClickedButtonQueryControlState) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_PROCESS_STATE, &CEAPSimulatorDlg::OnBnClickedButtonQueryProcessState) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_ALL_SVID, &CEAPSimulatorDlg::OnBnClickedButtonQueryAllSvid) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_ALL_DVID, &CEAPSimulatorDlg::OnBnClickedButtonQueryAllDvid) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_ALL_CEID, &CEAPSimulatorDlg::OnBnClickedButtonQueryAllCeid) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_ALL_ECID, &CEAPSimulatorDlg::OnBnClickedButtonQueryAllEcid) |
| | | ON_BN_CLICKED(IDC_BUTTON_SET_ECID, &CEAPSimulatorDlg::OnBnClickedButtonSetEcid) |
| | | ON_BN_CLICKED(IDC_BUTTON_QUERY_CURRENT_RECIPE, &CEAPSimulatorDlg::OnBnClickedButtonQueryCurrentRecipe) |
| | | ON_BN_CLICKED(IDC_BUTTON_PP_REQUEST, &CEAPSimulatorDlg::OnBnClickedButtonPpRequest) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | |
| | | // æ§è¡æ¤æä½ |
| | | SetIcon(m_hIcon, TRUE); // è®¾ç½®å¤§å¾æ |
| | | SetIcon(m_hIcon, FALSE); // 设置å°å¾æ |
| | | |
| | | // Add missing test button at runtime (resource file is UTF-16, keep it unchanged) |
| | | { |
| | | CRect rc(126, 120, 126 + 108, 120 + 14); // dialog units |
| | | MapDialogRect(&rc); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S3F17_ProceedWithSlotMap"), |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rc.left, rc.top, rc.Width(), rc.Height(), |
| | | m_hWnd, (HMENU)IDC_BUTTON_PROCEED_WITH_SLOTMAP, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn != nullptr) { |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | // ControlState test buttons at runtime (resource file is UTF-16, keep it unchanged) |
| | | { |
| | | const int y = 120; |
| | | const int w = 70; |
| | | const int h = 14; |
| | | const int gap = 3; |
| | | |
| | | struct BtnDef { int x; int id; const TCHAR* text; }; |
| | | BtnDef defs[] = { |
| | | { 238, IDC_BUTTON_CTRL_OFFLINE, _T("Ctrl Offline") }, |
| | | { 238 + (w + gap), IDC_BUTTON_CTRL_ONLINE_LOCAL, _T("Ctrl Local") }, |
| | | { 238 + 2 * (w + gap), IDC_BUTTON_CTRL_ONLINE_REMOTE, _T("Ctrl Remote") }, |
| | | }; |
| | | |
| | | for (const auto& d : defs) { |
| | | CRect rc(d.x, y, d.x + w, y + h); // dialog units |
| | | MapDialogRect(&rc); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), d.text, |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rc.left, rc.top, rc.Width(), rc.Height(), |
| | | m_hWnd, (HMENU)d.id, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn != nullptr) { |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | } |
| | | // S1F3 Query ControlState (SVID=600) button (runtime add to avoid touching UTF-16 RC) |
| | | { |
| | | // Place on its own row to avoid overlapping with control-mode buttons. |
| | | CRect rc(14, 136, 14 + 140, 136 + 14); // dialog units |
| | | MapDialogRect(&rc); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S1F3_QueryControlState"), |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rc.left, rc.top, rc.Width(), rc.Height(), |
| | | m_hWnd, (HMENU)IDC_BUTTON_QUERY_CONTROL_STATE, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn != nullptr) { |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | // S1F3 Query ProcessState (SVID=700) button |
| | | { |
| | | CRect rc(14 + 140 + 5, 136, 14 + 140 + 5 + 140, 136 + 14); // dialog units, same row offset |
| | | MapDialogRect(&rc); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S1F3_QueryProcessState"), |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rc.left, rc.top, rc.Width(), rc.Height(), |
| | | m_hWnd, (HMENU)IDC_BUTTON_QUERY_PROCESS_STATE, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn != nullptr) { |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | // S1F11 QueryAllSVID |
| | | { |
| | | CRect rc(14 + 140 + 5 + 140 + 5, 136, 14 + 140 + 5 + 140 + 5 + 140, 136 + 14); // dialog units, next row |
| | | MapDialogRect(&rc); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S1F11_QueryAllSVID"), |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rc.left, rc.top, rc.Width(), rc.Height(), |
| | | m_hWnd, (HMENU)IDC_BUTTON_QUERY_ALL_SVID, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn != nullptr) { |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | // S1F23 QueryAllCEID |
| | | { |
| | | CRect rc(14, 152, 14 + 140, 152 + 14); // dialog units, next row |
| | | MapDialogRect(&rc); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S1F23_QueryAllCEID"), |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rc.left, rc.top, rc.Width(), rc.Height(), |
| | | m_hWnd, (HMENU)IDC_BUTTON_QUERY_ALL_CEID, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn != nullptr) { |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | // S1F21 QueryAllDVID |
| | | { |
| | | CRect rc(14 + 140 + 5, 152, 14 + 140 + 5 + 140, 152 + 14); |
| | | MapDialogRect(&rc); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S1F21_QueryAllDVID"), |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rc.left, rc.top, rc.Width(), rc.Height(), |
| | | m_hWnd, (HMENU)IDC_BUTTON_QUERY_ALL_DVID, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn != nullptr) { |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | // S2F13 QueryAllECID |
| | | { |
| | | CRect rc(14 + 2 * (140 + 5), 192, 14 + 2 * (140 + 5) + 140, 192 + 14); |
| | | MapDialogRect(&rc); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S2F13_QueryAllECID"), |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rc.left, rc.top, rc.Width(), rc.Height(), |
| | | m_hWnd, (HMENU)IDC_BUTTON_QUERY_ALL_ECID, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn != nullptr) { |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | // ECID edit + send (S2F15) |
| | | { |
| | | CRect rcEcid(14, 192, 14 + 60, 192 + 14); |
| | | CRect rcEcv(14 + 60 + 4, 192, 14 + 60 + 4 + 60, 192 + 14); |
| | | MapDialogRect(&rcEcid); |
| | | MapDialogRect(&rcEcv); |
| | | HWND hEditEcid = ::CreateWindow(_T("EDIT"), _T(""), WS_CHILD | WS_VISIBLE | WS_BORDER, |
| | | rcEcid.left, rcEcid.top, rcEcid.Width(), rcEcid.Height(), |
| | | m_hWnd, (HMENU)IDC_EDIT_ECID, AfxGetInstanceHandle(), nullptr); |
| | | HWND hEditEcv = ::CreateWindow(_T("EDIT"), _T(""), WS_CHILD | WS_VISIBLE | WS_BORDER, |
| | | rcEcv.left, rcEcv.top, rcEcv.Width(), rcEcv.Height(), |
| | | m_hWnd, (HMENU)IDC_EDIT_ECV, AfxGetInstanceHandle(), nullptr); |
| | | if (hEditEcid) ::SendMessage(hEditEcid, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | if (hEditEcv) ::SendMessage(hEditEcv, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | |
| | | CRect rcBtn(14 + 60 + 4 + 60 + 4, 192, 14 + 60 + 4 + 60 + 4 + 90, 192 + 14); |
| | | MapDialogRect(&rcBtn); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S2F15_SetECID"), |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rcBtn.left, rcBtn.top, rcBtn.Width(), rcBtn.Height(), |
| | | m_hWnd, (HMENU)IDC_BUTTON_SET_ECID, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn) ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | // S1F3 CurrentRecipe (EQ specific) combo + button |
| | | { |
| | | CRect rcCombo(14, 168, 14 + 120, 168 + 120); // dropdown height arbitrary |
| | | MapDialogRect(&rcCombo); |
| | | HWND hCombo = ::CreateWindow(_T("COMBOBOX"), _T(""), |
| | | WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL, |
| | | rcCombo.left, rcCombo.top, rcCombo.Width(), rcCombo.Height(), |
| | | m_hWnd, (HMENU)IDC_COMBO_EQ_FOR_RECIPE, AfxGetInstanceHandle(), nullptr); |
| | | if (hCombo != nullptr) { |
| | | ::SendMessage(hCombo, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | // ç®åå¡«å
设å¤å表ï¼å¯æéè°æ´ï¼ |
| | | std::vector<CString> eqs = { _T("Bonder1"), _T("Bonder2"), _T("EFEM"), _T("VacuumBake"), _T("BakeCooling"), _T("Measurement") }; |
| | | for (const auto& eq : eqs) { |
| | | ::SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)eq); |
| | | } |
| | | ::SendMessage(hCombo, CB_SETCURSEL, 0, 0); |
| | | } |
| | | |
| | | CRect rcBtn(140, 168, 14 + 140 + 118, 168 + 14); |
| | | MapDialogRect(&rcBtn); |
| | | HWND hBtn = ::CreateWindow(_T("BUTTON"), _T("S1F3_CurrentRecipe"), |
| | | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| | | rcBtn.left, rcBtn.top, rcBtn.Width(), rcBtn.Height(), |
| | | m_hWnd, (HMENU)IDC_BUTTON_QUERY_CURRENT_RECIPE, AfxGetInstanceHandle(), nullptr); |
| | | if (hBtn != nullptr) { |
| | | ::SendMessage(hBtn, WM_SETFONT, (WPARAM)GetFont()->GetSafeHandle(), TRUE); |
| | | } |
| | | } |
| | | |
| | | SetDlgItemText(IDC_EDIT_IP, _T("127.0.0.1")); |
| | | SetDlgItemInt(IDC_EDIT_PORT, 7000); |
| | |
| | | GetDlgItem(IDC_BUTTON_TRANSMIT_SPOOLED_DATA)->EnableWindow(enabled); |
| | | GetDlgItem(IDC_BUTTON_PURGE_SPOOLED_DATA)->EnableWindow(enabled); |
| | | GetDlgItem(IDC_BUTTON_QUERY_PPID_LIST)->EnableWindow(enabled); |
| | | if (GetDlgItem(IDC_BUTTON_DELETE_PPID) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_DELETE_PPID)->EnableWindow(enabled); |
| | | } |
| | | if (GetDlgItem(IDC_EDIT_DELETE_PPID) != nullptr) { |
| | | GetDlgItem(IDC_EDIT_DELETE_PPID)->EnableWindow(enabled); |
| | | } |
| | | GetDlgItem(IDC_BUTTON_PROCEED_WITH_CARRIER)->EnableWindow(enabled); |
| | | if (GetDlgItem(IDC_BUTTON_PROCEED_WITH_SLOTMAP) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_PROCEED_WITH_SLOTMAP)->EnableWindow(enabled); |
| | | } |
| | | GetDlgItem(IDC_BUTTON_CARRIER_RELEASE)->EnableWindow(enabled); |
| | | GetDlgItem(IDC_BUTTON_QUERY_CJ_SPACE)->EnableWindow(enabled); |
| | | GetDlgItem(IDC_BUTTON_QUERY_PJ_SPACE)->EnableWindow(enabled); |
| | | GetDlgItem(IDC_BUTTON_CREATE_PJ)->EnableWindow(enabled); |
| | | GetDlgItem(IDC_BUTTON_CREATE_CJ)->EnableWindow(enabled); |
| | | if (GetDlgItem(IDC_BUTTON_CTRL_OFFLINE) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_CTRL_OFFLINE)->EnableWindow(enabled); |
| | | } |
| | | if (GetDlgItem(IDC_BUTTON_CTRL_ONLINE_LOCAL) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_CTRL_ONLINE_LOCAL)->EnableWindow(enabled); |
| | | } |
| | | if (GetDlgItem(IDC_BUTTON_CTRL_ONLINE_REMOTE) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_CTRL_ONLINE_REMOTE)->EnableWindow(enabled); |
| | | } |
| | | if (GetDlgItem(IDC_BUTTON_QUERY_CONTROL_STATE) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_QUERY_CONTROL_STATE)->EnableWindow(enabled); |
| | | } |
| | | if (GetDlgItem(IDC_BUTTON_QUERY_PROCESS_STATE) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_QUERY_PROCESS_STATE)->EnableWindow(enabled); |
| | | } |
| | | if (GetDlgItem(IDC_BUTTON_QUERY_ALL_SVID) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_QUERY_ALL_SVID)->EnableWindow(enabled); |
| | | } |
| | | if (GetDlgItem(IDC_BUTTON_QUERY_ALL_CEID) != nullptr) { |
| | | GetDlgItem(IDC_BUTTON_QUERY_ALL_CEID)->EnableWindow(enabled); |
| | | } |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonConnect() |
| | |
| | | theApp.m_model.m_pHsmsActive->hsmsQueryPPIDList(); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonDeletePpid() |
| | | { |
| | | CString strPPID; |
| | | GetDlgItemText(IDC_EDIT_DELETE_PPID, strPPID); |
| | | strPPID.Trim(); |
| | | std::vector<std::string> ppids; |
| | | if (!strPPID.IsEmpty()) { |
| | | CString upper = strPPID; |
| | | upper.MakeUpper(); |
| | | if (upper != _T("ALL")) { |
| | | int start = 0; |
| | | CString token = strPPID.Tokenize(_T(","), start); |
| | | while (!token.IsEmpty()) { |
| | | token.Trim(); |
| | | if (!token.IsEmpty()) { |
| | | ppids.push_back(std::string((LPTSTR)(LPCTSTR)token)); |
| | | } |
| | | token = strPPID.Tokenize(_T(","), start); |
| | | } |
| | | } |
| | | } |
| | | // L:0 if ppids empty -> delete all |
| | | theApp.m_model.m_pHsmsActive->hsmsDeletePPID(ppids); |
| | | } |
| | | |
| | | static int DATAID = 1; |
| | | void CEAPSimulatorDlg::OnBnClickedButtonProceedWithCarrier() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsProceedWithCarrier(DATAID++, "CSX 52078", 1); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonProceedWithSlotMap() |
| | | { |
| | | // Example payload (edit as needed) |
| | | std::vector<std::string> panelIds = { |
| | | "PANEL_01","PANEL_02","PANEL_03","PANEL_04", |
| | | "PANEL_05","PANEL_06","PANEL_07","PANEL_08" |
| | | }; |
| | | std::vector<unsigned char> slotMap = { |
| | | 3,3,1,1,1,1,1,1 // 1=Empty, 3=Exist |
| | | }; |
| | | theApp.m_model.m_pHsmsActive->hsmsProceedWithSlotMap(DATAID++, "CSX 52078", 1, "LOT_0001", panelIds, slotMap); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonCarrierRelease() |
| | |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonCreateCj() |
| | | { |
| | | std::vector<std::string> processJobIds = {"PJ0001", "PJ0003"}; |
| | | std::vector<std::string> processJobIds = {"PJ0001"}; |
| | | theApp.m_model.m_pHsmsActive->hsmsCreateControlJob("CJ5007", processJobIds); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonCtrlOffline() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsRequestOffline(); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonCtrlOnlineLocal() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsRequestOnline(); |
| | | theApp.m_model.m_pHsmsActive->hsmsGoLocal(); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonCtrlOnlineRemote() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsRequestOnline(); |
| | | theApp.m_model.m_pHsmsActive->hsmsGoRemote(); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonQueryControlState() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsSelectedEquipmentStatusRequest(SVID_ControlState); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonQueryProcessState() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsSelectedEquipmentStatusRequest(SVID_CurrentProcessState); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonQueryAllSvid() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsQueryAllStatusVariables(); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonQueryAllDvid() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsQueryAllDataVariables(); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonQueryAllCeid() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsQueryAllCollectionEvents(); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonQueryAllEcid() |
| | | { |
| | | // empty list => all ECID |
| | | std::vector<unsigned short> ecids; |
| | | ecids.push_back(2000); |
| | | theApp.m_model.m_pHsmsActive->hsmsEquipmentConstantRequest(ecids); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonSetEcid() |
| | | { |
| | | // simple demo: read ECID and value from edit boxes (reuse PPID edit) |
| | | CString sEcid, sVal; |
| | | GetDlgItemText(IDC_EDIT_ECID, sEcid); |
| | | GetDlgItemText(IDC_EDIT_ECV, sVal); |
| | | unsigned short id = static_cast<unsigned short>(_ttoi(sEcid)); |
| | | std::string val = CT2A(sVal); |
| | | std::vector<std::pair<unsigned short, std::string>> kvs; |
| | | if (id != 0) { |
| | | kvs.push_back({ id, val }); |
| | | theApp.m_model.m_pHsmsActive->hsmsEquipmentConstantSend(kvs); |
| | | } |
| | | } |
| | | void CEAPSimulatorDlg::OnBnClickedButtonQueryCurrentRecipe() |
| | | { |
| | | CString sel; |
| | | CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_EQ_FOR_RECIPE); |
| | | if (pCombo != nullptr) { |
| | | int idx = pCombo->GetCurSel(); |
| | | if (idx != CB_ERR) { |
| | | pCombo->GetLBText(idx, sel); |
| | | } |
| | | } |
| | | unsigned int svid = SVID_EQPPExecName; // é»è®¤å
¨å± |
| | | CString upper = sel; |
| | | upper.MakeUpper(); |
| | | if (upper.Find(_T("BONDER1")) != -1) svid = SVID_Bonder1CurrentRecipe; |
| | | else if (upper.Find(_T("BONDER2")) != -1) svid = SVID_Bonder2CurrentRecipe; |
| | | else if (upper.Find(_T("VACUUMBAKE")) != -1) svid = SVID_VacuumBakeCurrentRecipe; |
| | | else if (upper.Find(_T("BAKECOOLING")) != -1) svid = SVID_BakeCoolingCurrentRecipe; |
| | | else if (upper.Find(_T("MEASUREMENT")) != -1) svid = SVID_MeasurementCurrentRecipe; |
| | | else if (upper.Find(_T("EFEM")) != -1) svid = SVID_EFEMCurrentRecipe; |
| | | |
| | | theApp.m_model.m_pHsmsActive->hsmsSelectedEquipmentStatusRequest(svid); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonPpRequest() |
| | | { |
| | | CString strPPID; |
| | | GetDlgItemText(IDC_EDIT_PPID_REQ, strPPID); |
| | | strPPID.Trim(); |
| | | std::string ppid = CT2A(strPPID); |
| | | if (ppid.empty()) { |
| | | AfxMessageBox(_T("请è¾å
¥ PPID")); |
| | | return; |
| | | } |
| | | theApp.m_model.m_pHsmsActive->hsmsProcessProgramRequest(ppid.c_str()); |
| | | } |
| | |
| | | afx_msg void OnBnClickedButtonTransmitSpooledData(); |
| | | afx_msg void OnBnClickedButtonPurgeSpooledData(); |
| | | afx_msg void OnBnClickedButtonQueryPpidList(); |
| | | afx_msg void OnBnClickedButtonDeletePpid(); |
| | | afx_msg void OnBnClickedButtonProceedWithCarrier(); |
| | | afx_msg void OnBnClickedButtonProceedWithSlotMap(); |
| | | afx_msg void OnBnClickedButtonCarrierRelease(); |
| | | afx_msg void OnBnClickedButtonQueryCjSpace(); |
| | | afx_msg void OnBnClickedButtonQueryPjSpace(); |
| | | afx_msg void OnBnClickedButtonCreatePj(); |
| | | afx_msg void OnBnClickedButtonCreateCj(); |
| | | afx_msg void OnBnClickedButtonCtrlOffline(); |
| | | afx_msg void OnBnClickedButtonCtrlOnlineLocal(); |
| | | afx_msg void OnBnClickedButtonCtrlOnlineRemote(); |
| | | afx_msg void OnBnClickedButtonQueryControlState(); |
| | | afx_msg void OnBnClickedButtonQueryProcessState(); |
| | | afx_msg void OnBnClickedButtonQueryAllSvid(); |
| | | afx_msg void OnBnClickedButtonQueryAllDvid(); |
| | | afx_msg void OnBnClickedButtonQueryAllCeid(); |
| | | afx_msg void OnBnClickedButtonQueryAllEcid(); |
| | | afx_msg void OnBnClickedButtonSetEcid(); |
| | | afx_msg void OnBnClickedButtonQueryCurrentRecipe(); |
| | | afx_msg void OnBnClickedButtonPpRequest(); |
| | | }; |
| | |
| | | #define IDC_BUTTON_CREATE_PJ2 1040 |
| | | #define IDC_BUTTON_CREATE_CJ 1040 |
| | | #define IDC_BUTTON_DELETE 1041 |
| | | #define IDC_BUTTON_PROCEED_WITH_SLOTMAP 1042 |
| | | #define IDC_BUTTON_CTRL_OFFLINE 1043 |
| | | #define IDC_BUTTON_CTRL_ONLINE_LOCAL 1044 |
| | | #define IDC_BUTTON_CTRL_ONLINE_REMOTE 1045 |
| | | #define IDC_BUTTON_QUERY_CONTROL_STATE 1046 |
| | | #define IDC_BUTTON_QUERY_PROCESS_STATE 1047 |
| | | #define IDC_BUTTON_QUERY_ALL_SVID 1048 |
| | | #define IDC_BUTTON_QUERY_ALL_CEID 1049 |
| | | #define IDC_EDIT_DELETE_PPID 1050 |
| | | #define IDC_BUTTON_DELETE_PPID 1051 |
| | | #define IDC_COMBO_EQ_FOR_RECIPE 1052 |
| | | #define IDC_BUTTON_QUERY_CURRENT_RECIPE 1053 |
| | | #define IDC_EDIT_PPID_REQ 1054 |
| | | #define IDC_BUTTON_PP_REQUEST 1055 |
| | | #define IDC_BUTTON_QUERY_ALL_DVID 1056 |
| | | #define IDC_BUTTON_QUERY_ALL_ECID 1057 |
| | | #define IDC_EDIT_ECID 1058 |
| | | #define IDC_EDIT_ECV 1059 |
| | | #define IDC_BUTTON_SET_ECID 1060 |
| | | |
| | | // Next default values for new objects |
| | | // |
| | | #ifdef APSTUDIO_INVOKED |
| | | #ifndef APSTUDIO_READONLY_SYMBOLS |
| | | #define _APS_NEXT_RESOURCE_VALUE 143 |
| | | #define _APS_NEXT_RESOURCE_VALUE 146 |
| | | #define _APS_NEXT_COMMAND_VALUE 32771 |
| | | #define _APS_NEXT_CONTROL_VALUE 1042 |
| | | #define _APS_NEXT_CONTROL_VALUE 1057 |
| | | #define _APS_NEXT_SYMED_VALUE 101 |
| | | #endif |
| | | #endif |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "AccordionWnd.h" |
| | | |
| | | |
| | | #define ITEM_HEIGHT 32 |
| | | #define ITEM_SPACE 5 |
| | | #define TIMER_ID_CHECKHOVER 1 |
| | | #define EXPAND_ICON_WIDE 16 |
| | | |
| | | #define BORDER 5 |
| | | #define SHADOWWIDE 5 |
| | | |
| | | CAccordionWnd::CAccordionWnd() |
| | | { |
| | | m_hWnd = NULL; |
| | | m_crFrame = GetSysColor(COLOR_WINDOWFRAME); |
| | | m_crBkgnd = RGB(255, 255, 255);//GetSysColor(COLOR_BTNFACE); ; |
| | | m_nPadding[PADDING_LEFT] = 5; |
| | | m_nPadding[PADDING_TOP] = 5; |
| | | m_nPadding[PADDING_RIGHT] = 5; |
| | | m_nPadding[PADDING_BOTTOM] = 5; |
| | | m_crItemBackground[0] = RGB(218, 218, 218); |
| | | m_crItemBackground[1] = RGB(34, 177, 76); |
| | | m_crItemFrame[0] = RGB(128, 128, 128); |
| | | m_crItemFrame[1] = RGB(128, 128, 128); |
| | | m_crItemText[0] = RGB(68, 84, 111); |
| | | m_crItemText[1] = RGB(0, 0, 0); |
| | | m_crSeparateLine = RGB(222, 222, 222); |
| | | m_crHoverItemBackground = RGB(244, 245, 247); |
| | | m_crHoverItemFrame = RGB(200, 222, 255); |
| | | m_hIconExpand = NULL; |
| | | m_hIconClose = NULL; |
| | | m_nHoverItem = -1; |
| | | m_nCheckHoverItem = -1; |
| | | m_bShadow = FALSE; |
| | | m_crShadowBkgnd = GetSysColor(COLOR_BTNFACE); |
| | | } |
| | | |
| | | |
| | | CAccordionWnd::~CAccordionWnd() |
| | | { |
| | | for (size_t i = 0; i < m_vectorItems.size(); i++) { |
| | | delete m_vectorItems[i]; |
| | | } |
| | | m_vectorItems.clear(); |
| | | } |
| | | |
| | | BOOL CAccordionWnd::RegisterWndClass() |
| | | { |
| | | WNDCLASS wcExisting = {}; |
| | | HINSTANCE hInstance = AfxGetInstanceHandle(); |
| | | if (::GetClassInfo(hInstance, ACCORDIONWND_CLASS, &wcExisting) || |
| | | ::GetClassInfo(NULL, ACCORDIONWND_CLASS, &wcExisting)) { |
| | | return TRUE; |
| | | } |
| | | |
| | | WNDCLASS wc = {}; |
| | | wc.lpszClassName = ACCORDIONWND_CLASS; |
| | | wc.hInstance = hInstance; |
| | | wc.lpfnWndProc = WindowProc; |
| | | wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); |
| | | wc.hIcon = 0; |
| | | wc.lpszMenuName = NULL; |
| | | wc.hbrBackground = NULL; |
| | | wc.style = CS_GLOBALCLASS | CS_DBLCLKS; |
| | | wc.cbClsExtra = 0; |
| | | wc.cbWndExtra = 0; |
| | | |
| | | // 注åèªå®ä¹ç±» |
| | | if (::RegisterClass(&wc) != 0) { |
| | | return TRUE; |
| | | } |
| | | return (::GetLastError() == ERROR_CLASS_ALREADY_EXISTS); |
| | | } |
| | | |
| | | CAccordionWnd* CAccordionWnd::FromHandle(HWND hWnd) |
| | | { |
| | | CAccordionWnd* pAccordionWnd = (CAccordionWnd*)::GetProp(hWnd, ACCORDIONWND_TAG); |
| | | return pAccordionWnd; |
| | | } |
| | | |
| | | CAccordionWnd* CAccordionWnd::Hook(HWND hWnd) |
| | | { |
| | | CAccordionWnd* pAccordionWnd = (CAccordionWnd*)GetProp(hWnd, ACCORDIONWND_TAG); |
| | | if (pAccordionWnd == NULL) { |
| | | pAccordionWnd = new CAccordionWnd(); |
| | | pAccordionWnd->m_hWnd = hWnd; |
| | | |
| | | SetProp(hWnd, ACCORDIONWND_TAG, (HANDLE)pAccordionWnd); |
| | | } |
| | | |
| | | |
| | | return pAccordionWnd; |
| | | } |
| | | |
| | | void CAccordionWnd::LoadExpandIcon(CString strExpandFile, CString strCloseFile) |
| | | { |
| | | m_hIconExpand = (HICON)::LoadImage(AfxGetInstanceHandle(), strExpandFile, IMAGE_ICON, EXPAND_ICON_WIDE, EXPAND_ICON_WIDE, |
| | | LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); |
| | | m_hIconClose = (HICON)::LoadImage(AfxGetInstanceHandle(), strCloseFile, IMAGE_ICON, EXPAND_ICON_WIDE, EXPAND_ICON_WIDE, |
| | | LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); |
| | | } |
| | | |
| | | void CAccordionWnd::Setpadding(int type, unsigned int nPadding) |
| | | { |
| | | if (type >= PADDING_LEFT && PADDING_LEFT <= PADDING_BOTTOM) { |
| | | m_nPadding[type] = nPadding; |
| | | } |
| | | } |
| | | |
| | | void CAccordionWnd::SetDefaultItemBackgroundColor(COLORREF crNormal, COLORREF crSel) |
| | | { |
| | | m_crItemBackground[0] = crNormal; |
| | | m_crItemBackground[1] = crSel; |
| | | } |
| | | |
| | | void CAccordionWnd::SetDefaultItemFrameColor(COLORREF crNormal, COLORREF crSel) |
| | | { |
| | | m_crItemFrame[0] = crNormal; |
| | | m_crItemFrame[1] = crSel; |
| | | } |
| | | |
| | | void CAccordionWnd::SetDefaultItemTextColor(COLORREF crNormal, COLORREF crSel) |
| | | { |
| | | m_crItemText[0] = crNormal; |
| | | m_crItemText[1] = crSel; |
| | | } |
| | | |
| | | void CAccordionWnd::Init() |
| | | { |
| | | } |
| | | |
| | | void CAccordionWnd::Release() |
| | | { |
| | | // delete |
| | | delete this; |
| | | } |
| | | |
| | | /* |
| | | * æ·»å é¡¹ç® |
| | | * pszName -- åç§° |
| | | * pWnd -- ç»å®ççªå£ |
| | | * nExpandHeight -- å±å¼é«åº¦ï¼å¦æä¸º0åèªå¨è®¾ç½®ä¸ºçªå£é« |
| | | */ |
| | | void CAccordionWnd::AddItem(char* pszName, CWnd* pWnd, int nExpandHeight, BOOL bExpand/* = TRUE*/, BOOL bEnable/* = TRUE*/) |
| | | { |
| | | ACCORDIONITEM* pItem = new ACCORDIONITEM; |
| | | memset(pItem, 0, sizeof(ACCORDIONITEM)); |
| | | pItem->pWnd = pWnd; |
| | | pItem->bExpand = bExpand; |
| | | pItem->bEnable = bEnable; |
| | | strcpy_s(pItem->text, sizeof(pItem->text), pszName); |
| | | if (nExpandHeight == 0) { |
| | | RECT rect; |
| | | pWnd->GetWindowRect(&rect); |
| | | pItem->nExpandHeight = rect.bottom - rect.top; |
| | | } |
| | | else if (nExpandHeight == -1) { |
| | | pItem->nExpandHeight = -1; |
| | | } |
| | | else { |
| | | pItem->nExpandHeight = nExpandHeight; |
| | | } |
| | | m_vectorItems.push_back(pItem); |
| | | |
| | | |
| | | // éæ°è°æ´ä¸ªåçªå£çä½ç½® |
| | | ResizeItemWnd(); |
| | | } |
| | | |
| | | void CAccordionWnd::ResizeItemWnd() |
| | | { |
| | | RECT rcClient, rcItemClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | |
| | | for (size_t i = 0; i < m_vectorItems.size(); i++) { |
| | | ACCORDIONITEM* pItem = m_vectorItems.at(i); |
| | | if (pItem->pWnd != NULL) { |
| | | GetItemRect(rcClient, (UINT)i, &rcItemClient); |
| | | rcItemClient.top += ITEM_HEIGHT; |
| | | if (pItem->nExpandHeight == -1) { |
| | | rcItemClient.bottom = rcClient.bottom; |
| | | } |
| | | else { |
| | | rcItemClient.bottom = rcItemClient.top + pItem->nExpandHeight; |
| | | } |
| | | |
| | | pItem->pWnd->MoveWindow(&rcItemClient); |
| | | pItem->pWnd->ShowWindow(pItem->bExpand ? SW_SHOW : SW_HIDE); |
| | | } |
| | | } |
| | | } |
| | | |
| | | BOOL CAccordionWnd::GetItemHeaderRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect) |
| | | { |
| | | RECT rcItem; |
| | | if (!GetItemRect(rcClient, nIndex, &rcItem)) { |
| | | return FALSE; |
| | | } |
| | | |
| | | rcItem.bottom = rcItem.top + ITEM_HEIGHT; |
| | | CopyRect(lpRect, &rcItem); |
| | | return TRUE; |
| | | } |
| | | |
| | | BOOL CAccordionWnd::GetItemRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect) |
| | | { |
| | | if (nIndex >= m_vectorItems.size()) { |
| | | return FALSE; |
| | | } |
| | | |
| | | RECT rcItemHeader; |
| | | rcItemHeader.left = rcClient.left + m_nPadding[PADDING_LEFT]; |
| | | rcItemHeader.right = rcClient.right - m_nPadding[PADDING_RIGHT]; |
| | | rcItemHeader.top = rcClient.top + m_nPadding[PADDING_TOP]; |
| | | rcItemHeader.bottom = rcItemHeader.top + ITEM_HEIGHT; |
| | | for (size_t i = 0; i < m_vectorItems.size(); i++) { |
| | | ACCORDIONITEM* pItem = m_vectorItems.at(i); |
| | | if (pItem->bExpand) { |
| | | rcItemHeader.bottom += pItem->nExpandHeight; |
| | | } |
| | | |
| | | if (i == nIndex) { |
| | | break;; |
| | | } |
| | | |
| | | rcItemHeader.top = rcItemHeader.bottom + ITEM_SPACE; |
| | | rcItemHeader.bottom = rcItemHeader.top + ITEM_HEIGHT; |
| | | } |
| | | |
| | | |
| | | CopyRect(lpRect, &rcItemHeader); |
| | | return TRUE; |
| | | } |
| | | |
| | | int CAccordionWnd::HitTest(POINT pt, int& nHitTest) |
| | | { |
| | | int nRet = -1; |
| | | nHitTest = -1; |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | if (PtInRect(&rcClient, pt)) { |
| | | nRet = 1; |
| | | } |
| | | |
| | | int nItemIndex = -1; |
| | | RECT rcItemHeader; |
| | | for (size_t i = 0; i < m_vectorItems.size(); i++) { |
| | | GetItemHeaderRect(rcClient, (unsigned int)i, &rcItemHeader); |
| | | |
| | | if (PtInRect(&rcItemHeader, pt)) { |
| | | nItemIndex = (unsigned int)i; |
| | | |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (nItemIndex != -1) { |
| | | nRet = 2; |
| | | nHitTest = nItemIndex; |
| | | } |
| | | |
| | | return nRet; |
| | | } |
| | | |
| | | BOOL CAccordionWnd::Togle(unsigned int nIndex) |
| | | { |
| | | if (nIndex >= m_vectorItems.size()) { |
| | | return FALSE; |
| | | } |
| | | |
| | | ACCORDIONITEM* pItem = m_vectorItems[nIndex]; |
| | | pItem->bExpand = !pItem->bExpand; |
| | | |
| | | |
| | | // éæ°è°æ´ä¸ªåçªå£çä½ç½® |
| | | ResizeItemWnd(); |
| | | |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CAccordionWnd::Notify(int nCode, int dwData, int dwData1/* = 0*/, int dwData2/* = 0*/) |
| | | { |
| | | HWND hParent; |
| | | hParent = GetParent(m_hWnd); |
| | | if (hParent != NULL) { |
| | | ACCORDION_NMHDR accordionWndnmhdr; |
| | | accordionWndnmhdr.nmhdr.hwndFrom = m_hWnd; |
| | | accordionWndnmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID); |
| | | accordionWndnmhdr.nmhdr.code = nCode; |
| | | accordionWndnmhdr.dwData = dwData; |
| | | accordionWndnmhdr.dwData1 = dwData1; |
| | | accordionWndnmhdr.dwData2 = dwData2; |
| | | SendMessage(hParent, WM_NOTIFY, (WPARAM)accordionWndnmhdr.nmhdr.idFrom, (LPARAM)&accordionWndnmhdr); |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * æ¦æªçªå£æ¶æ¯å½æ° |
| | | */ |
| | | LRESULT CALLBACK CAccordionWnd::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
| | | { |
| | | CAccordionWnd* pAccordionWnd = (CAccordionWnd*)GetProp(hWnd, ACCORDIONWND_TAG); |
| | | if (pAccordionWnd == NULL && uMsg != WM_NCCREATE) |
| | | { |
| | | return ::DefWindowProc(hWnd, uMsg, wParam, lParam); |
| | | } |
| | | |
| | | |
| | | // 妿Hookåååºæ¶æ¯ |
| | | ASSERT(hWnd); |
| | | switch (uMsg) |
| | | { |
| | | case WM_NCCREATE: |
| | | return CAccordionWnd::OnNcCreate(hWnd, wParam, lParam); |
| | | |
| | | case WM_DESTROY: |
| | | return pAccordionWnd->OnDestroy(wParam, lParam); |
| | | |
| | | case WM_NCCALCSIZE: |
| | | return pAccordionWnd->OnNcCalcsize(wParam, lParam); |
| | | |
| | | case WM_NCPAINT: |
| | | return pAccordionWnd->OnNcPaint(wParam, lParam); |
| | | |
| | | case WM_PAINT: |
| | | return pAccordionWnd->OnPaint(wParam, lParam); |
| | | |
| | | case WM_TIMER: |
| | | return pAccordionWnd->OnTimer(wParam, lParam); |
| | | |
| | | case WM_MOUSEMOVE: |
| | | return pAccordionWnd->OnMouseMove(wParam, lParam); |
| | | |
| | | case WM_LBUTTONDOWN: |
| | | return pAccordionWnd->OnLButtonDown(wParam, lParam); |
| | | |
| | | case WM_LBUTTONUP: |
| | | return pAccordionWnd->OnLButtonUp(wParam, lParam); |
| | | |
| | | case WM_MOUSEWHEEL: |
| | | return pAccordionWnd->OnMouseWheel(wParam, lParam); |
| | | |
| | | case WM_SIZE: |
| | | return pAccordionWnd->OnSize(wParam, lParam); |
| | | |
| | | case WM_GETDLGCODE: |
| | | return DLGC_WANTALLKEYS; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | return ::DefWindowProc(hWnd, uMsg, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_NCCREATE |
| | | * çªå£å建åçåå§åå·¥ä½ |
| | | */ |
| | | LRESULT CAccordionWnd::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) |
| | | { |
| | | CAccordionWnd* pAccordionWnd = (CAccordionWnd*)GetProp(hWnd, ACCORDIONWND_TAG); |
| | | ASSERT(pAccordionWnd == NULL); |
| | | |
| | | Hook(hWnd); |
| | | return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_NCCALCSIZE |
| | | */ |
| | | LRESULT CAccordionWnd::OnNcCalcsize(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | if (!m_bShadow) { |
| | | return ::DefWindowProc(m_hWnd, WM_NCCALCSIZE, wParam, lParam); |
| | | } |
| | | |
| | | |
| | | LPRECT lprcWnd = (LPRECT)lParam; |
| | | lprcWnd->left += BORDER; |
| | | lprcWnd->top += BORDER; |
| | | lprcWnd->right -= (BORDER + SHADOWWIDE); |
| | | lprcWnd->bottom -= (BORDER + SHADOWWIDE); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /* |
| | | * WM_DESTROY |
| | | * çªå£éæ¯æ¶ |
| | | */ |
| | | LRESULT CAccordionWnd::OnDestroy(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | Release(); |
| | | return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam); |
| | | } |
| | | |
| | | |
| | | /* |
| | | * WM_TIMER |
| | | */ |
| | | LRESULT CAccordionWnd::OnTimer(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | int nTimerId = (int)wParam; |
| | | if (m_nTimerId == nTimerId) { |
| | | |
| | | POINT pt; |
| | | ::GetCursorPos(&pt); |
| | | ::ScreenToClient(m_hWnd, &pt); |
| | | |
| | | int nRet, nHitTest; |
| | | nRet = HitTest(pt, nHitTest); |
| | | if (m_nCheckHoverItem != nHitTest) { |
| | | KillTimer(m_hWnd, m_nTimerId); |
| | | m_nHoverItem = nHitTest; |
| | | m_nCheckHoverItem = nHitTest; |
| | | |
| | | RECT rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | } |
| | | |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_MOUSEMOVE |
| | | * é¼ æ ç§»å¨æ¶ï¼æ£æµé¼ æ ä½ç½®å¹¶åè°ç»ä¸»çªå£ |
| | | */ |
| | | LRESULT CAccordionWnd::OnMouseMove(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | POINT pt; |
| | | pt.x = (int)LOWORD(lParam); |
| | | pt.y = (int)HIWORD(lParam); |
| | | |
| | | int nRet, nHitTest; |
| | | nRet = HitTest(pt, nHitTest); |
| | | |
| | | if (nRet == 2) { |
| | | ACCORDIONITEM* pItem = m_vectorItems[nHitTest]; |
| | | if (pItem != NULL && pItem->bEnable) { |
| | | ::SetCursor(LoadCursor(NULL, IDC_HAND)); |
| | | } |
| | | } |
| | | else { |
| | | ::SetCursor(LoadCursor(NULL, IDC_ARROW)); |
| | | } |
| | | |
| | | int nLastItem = m_nHoverItem; |
| | | if (m_nHoverItem != nHitTest) { |
| | | m_nHoverItem = nHitTest; |
| | | |
| | | RECT rcClient, rcLastItemClient, rcCurItemClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | GetItemRect(rcClient, nLastItem, &rcLastItemClient); |
| | | ::InvalidateRect(m_hWnd, &rcLastItemClient, nHitTest < 0); |
| | | |
| | | if (nHitTest >= 0) { |
| | | ACCORDIONITEM* pItem = m_vectorItems.at(nHitTest); |
| | | if (!pItem->bEnable) { |
| | | m_nHoverItem = -1; |
| | | } |
| | | else { |
| | | KillTimer(m_hWnd, m_nTimerId); |
| | | m_nTimerId = SetTimer(m_hWnd, TIMER_ID_CHECKHOVER, 200, NULL); |
| | | m_nCheckHoverItem = m_nHoverItem; |
| | | |
| | | GetItemRect(rcClient, m_nHoverItem, &rcCurItemClient); |
| | | ::InvalidateRect(m_hWnd, &rcCurItemClient, TRUE); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_MOUSEMOVE, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_LBUTTONDOWN |
| | | * é¼ æ å·¦é®ä¸å |
| | | */ |
| | | LRESULT CAccordionWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | POINT pt; |
| | | pt.x = (int)LOWORD(lParam); |
| | | pt.y = (int)HIWORD(lParam); |
| | | |
| | | int nRet, nHitTest; |
| | | nRet = HitTest(pt, nHitTest); |
| | | |
| | | if (nRet == 2) { |
| | | ACCORDIONITEM* pItem = m_vectorItems[nHitTest]; |
| | | if (pItem != NULL && pItem->bEnable) { |
| | | ::SetCursor(LoadCursor(NULL, IDC_HAND)); |
| | | } |
| | | } |
| | | else { |
| | | ::SetCursor(LoadCursor(NULL, IDC_ARROW)); |
| | | } |
| | | |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_LBUTTONUP |
| | | * é¼ æ å·¦é®éæ¾ |
| | | */ |
| | | LRESULT CAccordionWnd::OnLButtonUp(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | POINT pt; |
| | | pt.x = (int)LOWORD(lParam); |
| | | pt.y = (int)HIWORD(lParam); |
| | | |
| | | int nRet, nHitTest; |
| | | nRet = HitTest(pt, nHitTest); |
| | | |
| | | if (nRet == 2) { |
| | | ACCORDIONITEM* pItem = m_vectorItems[nHitTest]; |
| | | if (pItem != NULL && pItem->bEnable) { |
| | | ::SetCursor(LoadCursor(NULL, IDC_HAND)); |
| | | Togle(nHitTest); |
| | | } |
| | | } |
| | | else { |
| | | ::SetCursor(LoadCursor(NULL, IDC_ARROW)); |
| | | } |
| | | |
| | | |
| | | return ::DefWindowProc(m_hWnd, WM_LBUTTONUP, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_MOUSEWHEEL |
| | | * é¼ æ æ»è½®æ»å¨æ¶ï¼ç¼©æ¾å¾å |
| | | */ |
| | | LRESULT CAccordionWnd::OnMouseWheel(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | return ::DefWindowProc(m_hWnd, WM_MOUSEWHEEL, wParam, lParam); |
| | | } |
| | | |
| | | /* |
| | | * WM_NCPAINT |
| | | */ |
| | | LRESULT CAccordionWnd::OnNcPaint(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | LRESULT lRet = ::DefWindowProc(m_hWnd, WM_NCPAINT, wParam, lParam); |
| | | |
| | | |
| | | // ç¶åç»è¾¹æ¡ |
| | | long styleEx = GetWindowLong(m_hWnd, GWL_EXSTYLE); |
| | | if ((styleEx & WS_EX_CLIENTEDGE) == WS_EX_CLIENTEDGE) { |
| | | |
| | | RECT rcWindow, rcClient; |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | ::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.left); |
| | | ::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.right); |
| | | GetWindowRect(m_hWnd, &rcWindow); |
| | | ::OffsetRect(&rcClient, -rcWindow.left, -rcWindow.top); |
| | | ::OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top); |
| | | |
| | | HRGN hRgnWnd = CreateRectRgnIndirect(&rcWindow); |
| | | HRGN hRgnClient = CreateRectRgnIndirect(&rcClient); |
| | | |
| | | HDC hDC = GetWindowDC(m_hWnd); |
| | | ::SelectClipRgn(hDC, hRgnWnd); |
| | | ::ExtSelectClipRgn(hDC, hRgnClient, RGN_DIFF); |
| | | |
| | | |
| | | // 没æé´å½±çè¾¹æ¡ |
| | | if (!m_bShadow) { |
| | | HBRUSH hBrushBK, hBrushFrame; |
| | | hBrushBK = CreateSolidBrush(m_crBkgnd); |
| | | ::FillRect(hDC, &rcWindow, hBrushBK); |
| | | DeleteObject(hBrushBK); |
| | | |
| | | hBrushFrame = CreateSolidBrush(m_crFrame); |
| | | ::FrameRect(hDC, &rcWindow, hBrushFrame); |
| | | DeleteObject(hBrushFrame); |
| | | } |
| | | |
| | | // æé´å½±çè¾¹æ¡ |
| | | else { |
| | | |
| | | RECT rcFrame0, rcFrame1; |
| | | rcFrame0.left = rcWindow.left + SHADOWWIDE; |
| | | rcFrame0.top = rcWindow.top + SHADOWWIDE; |
| | | rcFrame0.right = rcWindow.right; |
| | | rcFrame0.bottom = rcWindow.bottom; |
| | | rcFrame1.left = rcWindow.left; |
| | | rcFrame1.top = rcWindow.top; |
| | | rcFrame1.right = rcWindow.right - SHADOWWIDE; |
| | | rcFrame1.bottom = rcWindow.bottom - SHADOWWIDE; |
| | | |
| | | |
| | | // èæ¯æ¡åå¯¹è¯æ¡(ç¶çªä½)èæ¯è²ä¸è´ |
| | | HBRUSH hBrushBK, hBrushFrame; |
| | | hBrushBK = CreateSolidBrush(m_crShadowBkgnd); |
| | | ::FillRect(hDC, &rcWindow, hBrushBK); |
| | | DeleteObject(hBrushBK); |
| | | |
| | | |
| | | // é´å½±æ¡ |
| | | BYTE r = GetRValue(m_crShadowBkgnd); |
| | | BYTE g = GetGValue(m_crShadowBkgnd); |
| | | BYTE b = GetBValue(m_crShadowBkgnd); |
| | | BYTE rstep = (r - GetRValue(m_crFrame)) / SHADOWWIDE; |
| | | BYTE gstep = (r - GetGValue(m_crFrame)) / SHADOWWIDE; |
| | | BYTE bstep = (r - GetBValue(m_crFrame)) / SHADOWWIDE; |
| | | |
| | | for (int i = 0; i < SHADOWWIDE; i++) { |
| | | hBrushBK = CreateSolidBrush(RGB(r - i * rstep, g - i * gstep, b - i * bstep)); |
| | | ::FillRect(hDC, &rcFrame0, hBrushBK); |
| | | DeleteObject(hBrushBK); |
| | | rcFrame0.bottom -= 1; |
| | | rcFrame0.right -= 1; |
| | | } |
| | | |
| | | |
| | | // åæ¯æ¡ |
| | | hBrushBK = CreateSolidBrush(m_crBkgnd); |
| | | ::FillRect(hDC, &rcFrame1, hBrushBK); |
| | | DeleteObject(hBrushBK); |
| | | |
| | | hBrushFrame = CreateSolidBrush(m_crFrame); |
| | | ::FrameRect(hDC, &rcFrame1, hBrushFrame); |
| | | DeleteObject(hBrushFrame); |
| | | } |
| | | |
| | | |
| | | ::DeleteObject(hRgnWnd); |
| | | ::DeleteObject(hRgnClient); |
| | | ReleaseDC(m_hWnd, hDC); |
| | | } |
| | | |
| | | return lRet; |
| | | } |
| | | |
| | | /* |
| | | * WM_PAINT |
| | | */ |
| | | LRESULT CAccordionWnd::OnPaint(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | HDC hDC, hMemDC; |
| | | HBITMAP hBitmap; |
| | | RECT rcClient; |
| | | CString strText; |
| | | HFONT hFont; |
| | | HBRUSH hBrushBK; |
| | | |
| | | |
| | | // BeginPaint |
| | | PAINTSTRUCT ps; |
| | | hDC = BeginPaint(m_hWnd, &ps); |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | |
| | | hMemDC = ::CreateCompatibleDC(hDC); |
| | | hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right - rcClient.left, |
| | | rcClient.bottom - rcClient.top); |
| | | ::SelectObject(hMemDC, hBitmap); |
| | | ::SetBkMode(hMemDC, TRANSPARENT); |
| | | |
| | | |
| | | // èæ¯é¢è² |
| | | hBrushBK = CreateSolidBrush(m_crBkgnd); |
| | | ::FillRect(hMemDC, &rcClient, hBrushBK); |
| | | DeleteObject(hBrushBK); |
| | | |
| | | |
| | | // ç»å项å表 |
| | | hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); |
| | | ::SelectObject(hMemDC, hFont); |
| | | |
| | | HPEN hPenSeparate = ::CreatePen(PS_SOLID, 1, m_crSeparateLine); |
| | | RECT rcItem, rcItemHeader; |
| | | for (size_t i = 0; i < m_vectorItems.size(); i++) { |
| | | ACCORDIONITEM* pItem = m_vectorItems[i]; |
| | | GetItemRect(rcClient, (UINT)i, &rcItem); |
| | | GetItemHeaderRect(rcClient, (UINT)i, &rcItemHeader); |
| | | |
| | | |
| | | // çç¹é¡¹çèæ¯è²åè¾¹æ¡ |
| | | if (m_nHoverItem == (int)i) { |
| | | HBRUSH hbrItemHeaderBackground = CreateSolidBrush(m_crHoverItemBackground); |
| | | HBRUSH hbrItemFrame = CreateSolidBrush(m_crHoverItemFrame); |
| | | |
| | | HRGN hRgn = CreateRoundRectRgn(rcItemHeader.left, rcItemHeader.top, rcItemHeader.right, rcItemHeader.bottom, 2, 2); |
| | | ::FillRgn(hMemDC, hRgn, hbrItemHeaderBackground); |
| | | ::FrameRgn(hMemDC, hRgn, hbrItemFrame, 1, 1); |
| | | ::DeleteObject(hbrItemHeaderBackground); |
| | | ::DeleteObject(hbrItemFrame); |
| | | ::DeleteObject(hRgn); |
| | | } |
| | | |
| | | |
| | | // ç®å¤´ |
| | | BOOL bDrawIcon = DrawIconEx(hMemDC, rcItemHeader.left + (ITEM_HEIGHT - EXPAND_ICON_WIDE) / 2, rcItemHeader.top + (ITEM_HEIGHT - EXPAND_ICON_WIDE) / 2, |
| | | pItem->bExpand ? m_hIconExpand : m_hIconClose, EXPAND_ICON_WIDE, EXPAND_ICON_WIDE, 0, 0, DI_NORMAL); |
| | | |
| | | |
| | | // ææ¬ |
| | | ::SetTextColor(hMemDC, m_nHoverItem == (int)i ? m_crItemText[1] : m_crItemText[0]); |
| | | RECT rcText; |
| | | rcText.left = rcItemHeader.left + (bDrawIcon ? ITEM_HEIGHT : (ITEM_HEIGHT - EXPAND_ICON_WIDE) / 2); |
| | | rcText.top = rcItemHeader.top; |
| | | rcText.right = rcItemHeader.right; |
| | | rcText.bottom = rcItemHeader.bottom; |
| | | ::DrawText(hMemDC, pItem->text, (int)strlen(pItem->text), &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE); |
| | | |
| | | |
| | | // ææ¬å³è¾¹åé线 |
| | | SIZE sizeText; |
| | | GetTextExtentPoint32(hMemDC, pItem->text, (int)strlen(pItem->text), &sizeText); |
| | | |
| | | |
| | | HPEN hOldPen = (HPEN)::SelectObject(hMemDC, hPenSeparate); |
| | | MoveToEx(hMemDC, rcText.left + sizeText.cx + 10, rcItemHeader.top + (rcItemHeader.bottom - rcItemHeader.top - 1) / 2, NULL); |
| | | LineTo(hMemDC, rcItemHeader.right - 10, rcItemHeader.top + (rcItemHeader.bottom - rcItemHeader.top - 1) / 2); |
| | | ::SelectObject(hMemDC, hOldPen); |
| | | |
| | | |
| | | rcItemHeader.top = rcItemHeader.bottom + ITEM_SPACE; |
| | | rcItemHeader.bottom = rcItemHeader.top + ITEM_HEIGHT; |
| | | } |
| | | ::DeleteObject(hPenSeparate); |
| | | |
| | | |
| | | // EndPaint |
| | | ::BitBlt(hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, |
| | | hMemDC, 0, 0, SRCCOPY); |
| | | EndPaint(m_hWnd, &ps); |
| | | ::DeleteObject(hBitmap); |
| | | ::DeleteDC(hMemDC); |
| | | |
| | | |
| | | return 1; |
| | | } |
| | | |
| | | /* |
| | | * WM_SIZE |
| | | */ |
| | | LRESULT CAccordionWnd::OnSize(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | LRESULT lRet = ::DefWindowProc(m_hWnd, WM_SIZE, wParam, lParam); |
| | | |
| | | ResizeItemWnd(); |
| | | |
| | | return lRet; |
| | | } |
| | | |
| | | /* |
| | | * è®¾ç½®èæ¯è² |
| | | * color -- èæ¯è² |
| | | */ |
| | | void CAccordionWnd::SetBkgndColor(COLORREF color) |
| | | { |
| | | m_crBkgnd = color; |
| | | } |
| | | |
| | | |
| | | /* |
| | | * 设置é´å½±çèæ¯è²(å³ç¶çªå£çèæ¯) |
| | | * color -- èæ¯è² |
| | | */ |
| | | void CAccordionWnd::SetShadowBkgnd(COLORREF color) |
| | | { |
| | | m_crShadowBkgnd = color; |
| | | } |
| | | |
| | | /* |
| | | * 设置边æ¡é¢è² |
| | | * color -- è¾¹æ¡é¢è² |
| | | */ |
| | | void CAccordionWnd::SetFrameColor(COLORREF color, BOOL bShadow/* = FALSE*/) |
| | | { |
| | | m_crFrame = color; |
| | | m_bShadow = bShadow; |
| | | SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include <functional> |
| | | #include <vector> |
| | | |
| | | #ifndef ACCORDIONWND_TAG |
| | | |
| | | #ifdef _WIN32 |
| | | |
| | | #define ACCORDIONWND_CLASSA "AccordionWnd" |
| | | #define ACCORDIONWND_CLASSW L"AccordionWnd" |
| | | |
| | | #ifdef UNICODE |
| | | #define ACCORDIONWND_CLASS ACCORDIONWND_CLASSW |
| | | #else |
| | | #define ACCORDIONWND_CLASS ACCORDIONWND_CLASSA |
| | | #endif |
| | | |
| | | #else |
| | | #define ACCORDIONWND_CLASS "AccordionWnd" |
| | | #endif |
| | | |
| | | |
| | | #define ACCORDIONWND_TAG _T("ACCORDIONWND_TAG") |
| | | |
| | | #define ACCORDIONWND_FIRST (0U-3590U) |
| | | #define ACCORDIONWND_LAST (0U-5350U) |
| | | #define ACCORDIONWND_ONTOGLE (ACCORDIONWND_FIRST - 1) |
| | | |
| | | typedef struct tagACCORDION_NMHDR |
| | | { |
| | | NMHDR nmhdr; |
| | | DWORD dwData; |
| | | DWORD dwData1; |
| | | DWORD dwData2; |
| | | } ACCORDION_NMHDR; |
| | | |
| | | typedef struct tagACCORDIONITEM |
| | | { |
| | | unsigned int id; |
| | | int nExpandHeight; |
| | | COLORREF crBackground[2]; |
| | | COLORREF crFrame[2]; |
| | | COLORREF crText[2]; |
| | | char text[256]; |
| | | CWnd *pWnd; |
| | | BOOL bExpand; |
| | | BOOL bEnable; // æ¯å¦å¯ä»¥ç¹å»å±å¼åæ¶èµ· |
| | | } ACCORDIONITEM; |
| | | |
| | | #endif |
| | | |
| | | #define PADDING_LEFT 0 |
| | | #define PADDING_TOP 1 |
| | | #define PADDING_RIGHT 2 |
| | | #define PADDING_BOTTOM 3 |
| | | |
| | | class CAccordionWnd |
| | | { |
| | | public: |
| | | CAccordionWnd(); |
| | | ~CAccordionWnd(); |
| | | |
| | | |
| | | public: |
| | | static BOOL RegisterWndClass(); |
| | | static CAccordionWnd * FromHandle(HWND hWnd); |
| | | void SetFrameColor(COLORREF color, BOOL bShadow = FALSE); |
| | | void SetBkgndColor(COLORREF color); |
| | | void SetShadowBkgnd(COLORREF color); |
| | | |
| | | public: |
| | | void LoadExpandIcon(CString strExpandFile, CString strCloseFile); |
| | | void Setpadding(int type, unsigned int nPadding); |
| | | void SetDefaultItemBackgroundColor(COLORREF crNormal, COLORREF crSel); |
| | | void SetDefaultItemFrameColor(COLORREF crNormal, COLORREF crSel); |
| | | void SetDefaultItemTextColor(COLORREF crNormal, COLORREF crSel); |
| | | void AddItem(char *pszName, CWnd *pWnd, int nExpandHeight, BOOL bExpand = TRUE, BOOL bEnable = TRUE); |
| | | BOOL Togle(unsigned int nIndex); |
| | | int GetItemHeaderHeight(); |
| | | BOOL IsExpand(unsigned int nIndex); |
| | | |
| | | private: |
| | | void Init(); |
| | | void Notify(int nCode, int dwData, int dwData1 = 0, int dwData2 = 0); |
| | | void Release(); |
| | | void ResizeItemWnd(); |
| | | static CAccordionWnd* Hook(HWND hWnd); |
| | | static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); |
| | | static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnDestroy(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnTimer(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnNcPaint(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnNcCalcsize(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnPaint(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnMouseMove(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnLButtonUp(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnMouseWheel(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnSize(WPARAM wParam, LPARAM lParam); |
| | | |
| | | private: |
| | | HWND m_hWnd; |
| | | COLORREF m_crBkgnd; |
| | | COLORREF m_crFrame; |
| | | HICON m_hIconClose; |
| | | HICON m_hIconExpand; |
| | | int m_nHoverItem; |
| | | int m_nCheckHoverItem; |
| | | BOOL m_bShadow; // é´å½± |
| | | COLORREF m_crShadowBkgnd; // é´å½±èæ¯è²(å³ç¶çªå£çé¢è²) |
| | | |
| | | private: |
| | | unsigned int m_nPadding[4]; |
| | | COLORREF m_crItemBackground[2]; |
| | | COLORREF m_crItemFrame[2]; |
| | | COLORREF m_crItemText[2]; |
| | | COLORREF m_crSeparateLine; |
| | | COLORREF m_crHoverItemBackground; |
| | | COLORREF m_crHoverItemFrame; |
| | | CString m_strExpandIconFilepath[2]; |
| | | |
| | | private: |
| | | std::vector<ACCORDIONITEM *> m_vectorItems; |
| | | int m_nTimerId; |
| | | |
| | | private: |
| | | int HitTest(POINT pt, int &nHitTest); |
| | | BOOL GetItemHeaderRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect); |
| | | BOOL GetItemRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect); |
| | | }; |
| | | |
| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "Common.h" |
| | | #include "AlarmManager.h" |
| | | #include "Log.h" |
| | | #include <sstream> |
| | | #include <fstream> |
| | | #include <iostream> |
| | |
| | | #include <ctime> |
| | | #include <iomanip> |
| | | #include <random> |
| | | #include <chrono> |
| | | |
| | | // 常é |
| | | // 常é |
| | | const std::string DATABASE_FILE = R"(AlarmManager.db)"; |
| | | |
| | | // éææååå§å |
| | | // éææååå§å |
| | | std::mutex AlarmManager::m_mutex; |
| | | |
| | | // è·ååä¾å®ä¾ |
| | | // è·ååä¾å®ä¾ |
| | | AlarmManager& AlarmManager::getInstance() { |
| | | static AlarmManager instance; |
| | | return instance; |
| | | } |
| | | |
| | | // æé 彿° |
| | | // æé 彿° |
| | | AlarmManager::AlarmManager() { |
| | | m_pDB = new BL::SQLiteDatabase(); |
| | | } |
| | | |
| | | // ææå½æ° |
| | | // ææå½æ° |
| | | AlarmManager::~AlarmManager() { |
| | | if (m_pDB != nullptr) { |
| | | delete m_pDB; |
| | |
| | | } |
| | | } |
| | | |
| | | // åå§åæ¥è¦è¡¨ |
| | | // åå§åæ¥è¦è¡¨ |
| | | bool AlarmManager::initAlarmTable() { |
| | | char path[MAX_PATH]; |
| | | GetModuleFileName(NULL, path, MAX_PATH); |
| | |
| | | throw std::runtime_error("Failed to connect to database."); |
| | | } |
| | | |
| | | // å建设å¤è¡¨ |
| | | // å建设å¤è¡¨ |
| | | const std::string createDevicesTableQuery = R"( |
| | | CREATE TABLE IF NOT EXISTS devices ( |
| | | device_id TEXT PRIMARY KEY NOT NULL, |
| | |
| | | return false; |
| | | } |
| | | |
| | | // å建åå
表ï¼è®¾å¤IDååå
IDç»åä½ä¸ºä¸»é® |
| | | // å建åå
表ï¼è®¾å¤IDååå
IDç»åä½ä¸ºä¸»é® |
| | | const std::string createUnitsTableQuery = R"( |
| | | CREATE TABLE IF NOT EXISTS units ( |
| | | device_id TEXT NOT NULL, |
| | |
| | | return false; |
| | | } |
| | | |
| | | // å建æ¥è¦è¡¨ï¼æ¥è¦è®°å½çalarm_event_idæ¯ä¸»é® |
| | | // å建æ¥è¦è¡¨ï¼æ¥è¦è®°å½çalarm_event_idæ¯ä¸»é® |
| | | const std::string createAlarmsTableQuery = R"( |
| | | CREATE TABLE IF NOT EXISTS alarms ( |
| | | alarm_event_id INTEGER PRIMARY KEY AUTOINCREMENT, |
| | |
| | | return false; |
| | | } |
| | | |
| | | // 设å¤å表 (ID -> åç§°) |
| | | // 设å¤å表 (ID -> åç§°) |
| | | std::vector<std::pair<int, std::string>> devices = { |
| | | {0, "Software"}, |
| | | {EQ_ID_LOADPORT1, EQ_NAME_LOADPORT1}, |
| | | {EQ_ID_LOADPORT2, EQ_NAME_LOADPORT2}, |
| | | {EQ_ID_LOADPORT3, EQ_NAME_LOADPORT3}, |
| | |
| | | {EQ_ID_OPERATOR_REMOVE, EQ_NAME_OPERATOR_REMOVE} |
| | | }; |
| | | |
| | | // æå
¥ devices å对åºçé»è®¤ unit |
| | | // æå
¥ devices å对åºçé»è®¤ unit |
| | | for (const auto& dev : devices) { |
| | | int nDeviceId = dev.first; |
| | | const std::string& strDeviceName = dev.second; |
| | | |
| | | // æå
¥è®¾å¤ |
| | | // æå
¥è®¾å¤ |
| | | std::ostringstream ossDev; |
| | | ossDev << "INSERT OR IGNORE INTO devices (device_id, device_name) VALUES(" |
| | | << nDeviceId << ", '" << strDeviceName << "')"; |
| | |
| | | return false; |
| | | } |
| | | |
| | | // æå
¥é»è®¤åå
(unit_id = 0, unit_name = device_name) |
| | | // æå
¥é»è®¤åå
(unit_id = 0, unit_name = device_name) |
| | | std::ostringstream ossUnit; |
| | | ossUnit << "INSERT OR IGNORE INTO units (device_id, unit_id, unit_name) VALUES(" |
| | | << nDeviceId << ", 0, '" << strDeviceName << "')"; |
| | |
| | | return true; |
| | | } |
| | | |
| | | // 鿝æ¥è¦è¡¨ |
| | | // 鿝æ¥è¦è¡¨ |
| | | void AlarmManager::termAlarmTable() { |
| | | if (m_pDB != nullptr) { |
| | | m_pDB->disconnect(); |
| | | } |
| | | } |
| | | |
| | | // 鿝æ¥è¦è¡¨ |
| | | // 鿝æ¥è¦è¡¨ |
| | | bool AlarmManager::destroyAlarmTable() { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | |
| | | return m_pDB->executeQuery(dropTableQuery); |
| | | } |
| | | |
| | | // æå
¥æ¨¡ææ°æ® |
| | | // æå
¥æ¨¡ææ°æ® |
| | | void AlarmManager::insertMockData() { |
| | | // æå
¥è®¾å¤æ°æ® |
| | | // æå
¥è®¾å¤æ°æ® |
| | | for (int i = 1; i <= 3; ++i) { |
| | | std::string deviceName = "Device" + std::to_string(i); |
| | | std::stringstream query; |
| | |
| | | } |
| | | } |
| | | |
| | | // æå
¥åå
æ°æ® |
| | | // æå
¥åå
æ°æ® |
| | | for (int i = 1; i <= 3; ++i) { |
| | | for (int j = 0; j <= 3; ++j) { |
| | | int unitId = j; |
| | |
| | | |
| | | std::stringstream query; |
| | | query << "INSERT INTO units (device_id, unit_id, unit_name) VALUES ('" |
| | | << deviceId << "', '" // æå
¥è®¾å¤IDï¼ç¡®ä¿æ¯å符串 |
| | | << unitId << "', '" // æå
¥åå
IDï¼ç¡®ä¿æ¯å符串 |
| | | << deviceId << "', '" // æå
¥è®¾å¤IDï¼ç¡®ä¿æ¯å符串 |
| | | << unitId << "', '" // æå
¥åå
IDï¼ç¡®ä¿æ¯å符串 |
| | | << unitName << "');"; |
| | | |
| | | if (!m_pDB->executeQuery(query.str())) { |
| | |
| | | } |
| | | |
| | | /* |
| | | // åå§åéæºæ°çæå¨ |
| | | // åå§åéæºæ°çæå¨ |
| | | std::random_device rd; |
| | | std::mt19937 gen(rd()); |
| | | std::uniform_int_distribution<> deviceDis(1, 3); |
| | |
| | | std::uniform_int_distribution<> severityDis(0, 3); |
| | | std::vector<std::string> descriptions = { "Overheat", "Sensor failure", "Power outage" }; |
| | | |
| | | // æ¶é´ç¸å
³ |
| | | // æ¶é´ç¸å
³ |
| | | auto now = std::chrono::system_clock::now(); |
| | | auto start_time = std::chrono::system_clock::to_time_t(now); |
| | | auto end_time = std::chrono::system_clock::to_time_t(now + std::chrono::minutes(10)); |
| | |
| | | localtime_s(&start_tm, &start_time); |
| | | localtime_s(&end_tm, &end_time); |
| | | |
| | | // æå
¥æ¨¡ææ°æ® |
| | | // æå
¥æ¨¡ææ°æ® |
| | | for (int i = 0; i < 10; ++i) { |
| | | int deviceId = deviceDis(gen); // éæºè®¾å¤ID |
| | | int unitId = unitDis(gen); // éæºåå
ID |
| | | int errorCode = errorCodeDis(gen); // éæºé误ç |
| | | int severityLevel = severityDis(gen); // éæºçææ¥è¦ç级 |
| | | std::string description = descriptions[errorCodeDis(gen) % descriptions.size()]; // éæºæ¥è¦æè¿° |
| | | int deviceId = deviceDis(gen); // éæºè®¾å¤ID |
| | | int unitId = unitDis(gen); // éæºåå
ID |
| | | int errorCode = errorCodeDis(gen); // éæºé误ç |
| | | int severityLevel = severityDis(gen); // éæºçææ¥è¦ç级 |
| | | std::string description = descriptions[errorCodeDis(gen) % descriptions.size()]; // éæºæ¥è¦æè¿° |
| | | |
| | | std::stringstream query; |
| | | query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) " |
| | |
| | | */ |
| | | } |
| | | |
| | | // æ·»å æ¥è¦ä¿¡æ¯ |
| | | // æ·»å æ¥è¦ä¿¡æ¯ |
| | | bool AlarmManager::addAlarm(const AlarmData& alarmData, int& alarmEventId) { |
| | | if (!m_pDB) { |
| | | return false; |
| | | } |
| | | |
| | | #if 0 |
| | | // å¼å§äºå¡ |
| | | // å¼å§äºå¡ |
| | | m_pDB->executeQuery("BEGIN TRANSACTION;"); |
| | | |
| | | // æå»ºæå
¥æ¥è¯¢ |
| | | // æå»ºæå
¥æ¥è¯¢ |
| | | std::ostringstream query; |
| | | query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) VALUES (" |
| | | << alarmData.nId << ", " // é误ç |
| | | << alarmData.nSeverityLevel << ", " // æ¥è¦ç级 |
| | | << alarmData.nDeviceId << ", " // 设å¤ID |
| | | << alarmData.nUnitId << ", '" // åå
ID |
| | | << alarmData.strDescription << "', '" // æè¿° |
| | | << alarmData.strStartTime << "', '" // å¼å§æ¶é´ |
| | | << alarmData.strEndTime << "')"; // ç»ææ¶é´ |
| | | << alarmData.nId << ", " // é误ç |
| | | << alarmData.nSeverityLevel << ", " // æ¥è¦ç级 |
| | | << alarmData.nDeviceId << ", " // 设å¤ID |
| | | << alarmData.nUnitId << ", '" // åå
ID |
| | | << alarmData.strDescription << "', '" // æè¿° |
| | | << alarmData.strStartTime << "', '" // å¼å§æ¶é´ |
| | | << alarmData.strEndTime << "')"; // ç»ææ¶é´ |
| | | |
| | | // 使ç¨éä¿æ¤å¤çº¿ç¨å®å
¨ |
| | | // 使ç¨éä¿æ¤å¤çº¿ç¨å®å
¨ |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | |
| | | // æ§è¡æå
¥æ¥è¯¢ |
| | | // æ§è¡æå
¥æ¥è¯¢ |
| | | bool result = m_pDB->executeQuery(query.str()); |
| | | if (result) { |
| | | alarmEventId = getLastInsertId(); |
| | | m_alarmCache[alarmEventId] = alarmData; |
| | | } |
| | | |
| | | // æäº¤äºå¡ |
| | | // æäº¤äºå¡ |
| | | m_pDB->executeQuery("COMMIT;"); |
| | | |
| | | return result; |
| | |
| | | } |
| | | } |
| | | |
| | | // æå»ºæå
¥æ¥è¯¢å¹¶ä½¿ç¨ RETURNING è·åæå
¥åç alarm_event_id |
| | | // æå»ºæå
¥æ¥è¯¢å¹¶ä½¿ç¨ RETURNING è·åæå
¥åç alarm_event_id |
| | | std::ostringstream query; |
| | | query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) " |
| | | << "VALUES (" << alarmData.nId << ", " << alarmData.nSeverityLevel << ", " << alarmData.nDeviceId << ", " |
| | | << alarmData.nUnitId << ", '" << alarmData.strDescription << "', '" << alarmData.strStartTime << "', '" |
| | | << alarmData.strEndTime << "') RETURNING alarm_event_id;"; |
| | | |
| | | // 使ç¨éä¿æ¤å¤çº¿ç¨å®å
¨ |
| | | // 使ç¨éä¿æ¤å¤çº¿ç¨å®å
¨ |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | |
| | | // æ§è¡æ¥è¯¢å¹¶è·åç»æ |
| | | // æ§è¡æ¥è¯¢å¹¶è·åç»æ |
| | | auto results = m_pDB->fetchResults(query.str()); |
| | | if (!results.empty() && !results[0].empty()) { |
| | | try { |
| | | // æåå¹¶è½¬æ¢ alarm_event_id |
| | | // æåå¹¶è½¬æ¢ alarm_event_id |
| | | alarmEventId = std::stoi(results[0][0]); |
| | | // å°æå
¥çæ¥è¦æ°æ®æ·»å å°ç¼å |
| | | // å°æå
¥çæ¥è¦æ°æ®æ·»å å°ç¼å |
| | | m_mapCache[alarmEventId] = alarmData; |
| | | return true; |
| | | } |
| | |
| | | #endif |
| | | } |
| | | |
| | | // æ¥è¯¢æææ¥è¦æ°æ® |
| | | // æ¥è¯¢æææ¥è¦æ°æ® |
| | | std::vector<AlarmData> AlarmManager::getAllAlarms() { |
| | | if (!m_pDB) { |
| | | return {}; |
| | | } |
| | | |
| | | // æ¥è¯¢æææ¥è¦æ°æ®ï¼å
æ¬è®¾å¤åç§°ååå
åç§°ï¼ |
| | | // æ¥è¯¢æææ¥è¦æ°æ®ï¼å
æ¬è®¾å¤åç§°ååå
åç§°ï¼ |
| | | const std::string query = R"( |
| | | SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time |
| | | FROM alarms a |
| | |
| | | |
| | | auto results = m_pDB->fetchResults(query); |
| | | |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | std::vector<AlarmData> alarms; |
| | | for (const auto& row : results) { |
| | | AlarmData alarmData; |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | |
| | | alarms.push_back(alarmData); |
| | | } |
| | |
| | | return alarms; |
| | | } |
| | | |
| | | // æ ¹æ®æ¥è¦IDæ¥è¯¢æ¥è¦ |
| | | // æ ¹æ®æ¥è¦IDæ¥è¯¢æ¥è¦ |
| | | std::vector<AlarmData> AlarmManager::getAlarmsById(const std::string& id) { |
| | | if (!m_pDB) { |
| | | return {}; |
| | |
| | | |
| | | auto results = m_pDB->fetchResults(query.str()); |
| | | |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | std::vector<AlarmData> alarms; |
| | | for (const auto& row : results) { |
| | | AlarmData alarmData; |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | |
| | | alarms.push_back(alarmData); |
| | | } |
| | |
| | | return alarms; |
| | | } |
| | | |
| | | // æ ¹æ®æè¿°æ¥è¯¢æ¥è¦ |
| | | // æ ¹æ®æè¿°æ¥è¯¢æ¥è¦ |
| | | std::vector<AlarmData> AlarmManager::getAlarmsByDescription(const std::string& description) { |
| | | if (!m_pDB) { |
| | | return {}; |
| | |
| | | |
| | | auto results = m_pDB->fetchResults(query.str()); |
| | | |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | std::vector<AlarmData> alarms; |
| | | for (const auto& row : results) { |
| | | AlarmData alarmData; |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | |
| | | alarms.push_back(alarmData); |
| | | } |
| | |
| | | return alarms; |
| | | } |
| | | |
| | | // æ ¹æ®æ¶é´èå´æ¥è¯¢æ¥è¦ |
| | | // æ ¹æ®æ¶é´èå´æ¥è¯¢æ¥è¦ |
| | | std::vector<AlarmData> AlarmManager::getAlarmsByTimeRange(const std::string& startTime, const std::string& endTime) { |
| | | if (!m_pDB) { |
| | | return {}; |
| | |
| | | |
| | | auto results = m_pDB->fetchResults(query.str()); |
| | | |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | std::vector<AlarmData> alarms; |
| | | for (const auto& row : results) { |
| | | AlarmData alarmData; |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | |
| | | alarms.push_back(alarmData); |
| | | } |
| | |
| | | return alarms; |
| | | } |
| | | |
| | | // æ ¹æ®IDãå¼å§æ¶é´åç»ææ¶é´æ¥è¯¢æ¥è¦ |
| | | // æ ¹æ®IDãå¼å§æ¶é´åç»ææ¶é´æ¥è¯¢æ¥è¦ |
| | | std::vector<AlarmData> AlarmManager::getAlarmsByIdAndTimeRange(const std::string& id, const std::string& startTime, const std::string& endTime) { |
| | | if (!m_pDB) { |
| | | return {}; |
| | |
| | | |
| | | auto results = m_pDB->fetchResults(query.str()); |
| | | |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | std::vector<AlarmData> alarms; |
| | | for (const auto& row : results) { |
| | | AlarmData alarmData; |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | |
| | | alarms.push_back(alarmData); |
| | | } |
| | |
| | | return alarms; |
| | | } |
| | | |
| | | // å页æ¥è¯¢æ¥è¦æ°æ® |
| | | // å页æ¥è¯¢æ¥è¦æ°æ® |
| | | std::vector<AlarmData> AlarmManager::getAlarms(int startPosition, int count) { |
| | | if (!m_pDB) { |
| | | return {}; |
| | |
| | | |
| | | auto results = m_pDB->fetchResults(query.str()); |
| | | |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | std::vector<AlarmData> alarms; |
| | | for (const auto& row : results) { |
| | | AlarmData alarmData; |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | |
| | | alarms.push_back(alarmData); |
| | | } |
| | |
| | | return alarms; |
| | | } |
| | | |
| | | // çéæ¥è¦æ°æ® |
| | | // è·åå½åæªç»æçæ¥è¦ï¼end_time 为空ï¼ï¼å¹¶å¯æ start_time æè¿ N å°æ¶è¿æ»¤ |
| | | std::vector<AlarmData> AlarmManager::getActiveAlarms(int recentHours /*=12*/) { |
| | | if (!m_pDB) { |
| | | return {}; |
| | | } |
| | | |
| | | // è®¡ç®æ¶é´éå¼ï¼å½åæ¶é´å recentHours |
| | | std::string cutoffTime; |
| | | if (recentHours > 0) { |
| | | using namespace std::chrono; |
| | | auto cutoff = system_clock::now() - hours(recentHours); |
| | | std::time_t t = system_clock::to_time_t(cutoff); |
| | | std::tm tm {}; |
| | | localtime_s(&tm, &t); |
| | | char buf[32] = { 0 }; |
| | | std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm); |
| | | cutoffTime = buf; |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | query << R"( |
| | | SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time |
| | | FROM alarms a |
| | | JOIN devices d ON a.device_id = d.device_id |
| | | JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id |
| | | WHERE a.end_time IS NULL OR a.end_time = '' |
| | | )"; |
| | | if (!cutoffTime.empty()) { |
| | | query << " AND a.start_time >= '" << cutoffTime << "'"; |
| | | } |
| | | query << " ORDER BY a.start_time DESC"; |
| | | |
| | | auto lastErrStr = []() -> std::string { |
| | | DWORD gle = GetLastError(); |
| | | if (gle == 0) return {}; |
| | | LPSTR buf = nullptr; |
| | | size_t len = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, |
| | | nullptr, gle, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, nullptr); |
| | | std::string s = (buf && len > 0) ? std::string(buf, len) : ""; |
| | | if (buf) LocalFree(buf); |
| | | return s; |
| | | }; |
| | | std::vector<std::vector<std::string>> results; |
| | | try { |
| | | results = m_pDB->fetchResults(query.str()); |
| | | } |
| | | catch (const std::exception& ex) { |
| | | DWORD gle = GetLastError(); |
| | | auto errStr = lastErrStr(); |
| | | LOGE("<AlarmManager>getActiveAlarms failed: %s, GLE=%lu (%s)", ex.what(), gle, errStr.c_str()); |
| | | return {}; |
| | | } |
| | | std::vector<AlarmData> alarms; |
| | | auto toInt = [](const std::string& s) -> int { |
| | | try { |
| | | return std::stoi(s); |
| | | } |
| | | catch (...) { |
| | | return 0; |
| | | } |
| | | }; |
| | | for (const auto& row : results) { |
| | | if (row.size() < 9) continue; |
| | | AlarmData alarmData; |
| | | alarmData.nId = toInt(row[0]); |
| | | alarmData.nSeverityLevel = toInt(row[1]); |
| | | alarmData.nDeviceId = toInt(row[2]); |
| | | alarmData.nUnitId = toInt(row[3]); |
| | | alarmData.strDeviceName = row[4]; |
| | | alarmData.strUnitName = row[5]; |
| | | alarmData.strDescription = row[6]; |
| | | alarmData.strStartTime = row[7]; |
| | | alarmData.strEndTime = row[8]; |
| | | alarms.push_back(alarmData); |
| | | } |
| | | |
| | | return alarms; |
| | | } |
| | | |
| | | // çéæ¥è¦æ°æ® |
| | | std::vector<AlarmData> AlarmManager::getFilteredAlarms(const std::string& keyword, const std::string& startTime, const std::string& endTime, int pageNumber, int pageSize) { |
| | | if (!m_pDB) { |
| | | return {}; |
| | |
| | | JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id |
| | | WHERE 1=1)"; |
| | | |
| | | // ç»ä¸å
³é®åæ¨¡ç³æ¥è¯¢ |
| | | // ç»ä¸å
³é®åæ¨¡ç³æ¥è¯¢ |
| | | if (!keyword.empty()) { |
| | | query << " AND (" |
| | | << "a.id LIKE '%" << keyword << "%' OR " |
| | |
| | | << "a.description LIKE '%" << keyword << "%')"; |
| | | } |
| | | |
| | | // æ¶é´æ¡ä»¶ |
| | | // æ¶é´æ¡ä»¶ |
| | | if (!startTime.empty()) { |
| | | query << " AND a.start_time >= '" << startTime << "'"; |
| | | } |
| | |
| | | query << " AND a.end_time <= '" << endTime << "'"; |
| | | } |
| | | |
| | | // å页设置 |
| | | // å页设置 |
| | | int nOffset = (pageNumber - 1) * pageSize; |
| | | query << " ORDER BY a.start_time DESC LIMIT " << pageSize << " OFFSET " << nOffset; |
| | | |
| | | // æ¥è¯¢ |
| | | // æ¥è¯¢ |
| | | auto results = m_pDB->fetchResults(query.str()); |
| | | |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | // éåæ¥è¯¢ç»æï¼å¡«å
AlarmData ç»æä½ |
| | | std::vector<AlarmData> alarms; |
| | | for (const auto& row : results) { |
| | | AlarmData alarmData; |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 (å符串) |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | alarmData.nId = std::stoi(row[0]); // é误ç |
| | | alarmData.nSeverityLevel = std::stoi(row[1]); // æ¥è¦ç级 (å符串) |
| | | alarmData.nDeviceId = std::stoi(row[2]); // 设å¤ID |
| | | alarmData.nUnitId = std::stoi(row[3]); // åå
ID |
| | | alarmData.strDeviceName = row[4]; // 设å¤åç§° |
| | | alarmData.strUnitName = row[5]; // åå
åç§° |
| | | alarmData.strDescription = row[6]; // æè¿° |
| | | alarmData.strStartTime = row[7]; // å¼å§æ¶é´ |
| | | alarmData.strEndTime = row[8]; // ç»ææ¶é´ |
| | | |
| | | alarms.push_back(alarmData); |
| | | } |
| | |
| | | return alarms; |
| | | } |
| | | |
| | | // è·åç¬¦åæ¡ä»¶çæ¥è¦æ»æ° |
| | | // è·åç¬¦åæ¡ä»¶çæ¥è¦æ»æ° |
| | | int AlarmManager::getTotalAlarmCount(const std::string& keyword, const std::string& startTime, const std::string& endTime) { |
| | | if (!m_pDB) { |
| | | return 0; |
| | |
| | | JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id |
| | | WHERE 1=1)"; |
| | | |
| | | // ç»ä¸å
³é®åæ¨¡ç³æ¥è¯¢ |
| | | // ç»ä¸å
³é®åæ¨¡ç³æ¥è¯¢ |
| | | if (!keyword.empty()) { |
| | | query << " AND (" |
| | | << "a.id LIKE '%" << keyword << "%' OR " |
| | |
| | | << "a.description LIKE '%" << keyword << "%')"; |
| | | } |
| | | |
| | | // æ¶é´æ¡ä»¶ |
| | | // æ¶é´æ¡ä»¶ |
| | | if (!startTime.empty()) { |
| | | query << " AND a.start_time >= '" << startTime << "'"; |
| | | } |
| | |
| | | return (!results.empty() && !results[0].empty()) ? std::stoi(results[0][0]) : 0; |
| | | } |
| | | |
| | | // æ´æ°æ¥è¦çç»ææ¶é´ |
| | | // æ´æ°æ¥è¦çç»ææ¶é´ |
| | | bool AlarmManager::updateAlarmEndTime( |
| | | const std::string& id, |
| | | const std::string& severityLevel, |
| | |
| | | return false; |
| | | } |
| | | |
| | | // æ´æ°æ¥è¦ç»ææ¶é´ |
| | | // æ´æ°æ¥è¦ç»ææ¶é´ |
| | | std::ostringstream updateQuery; |
| | | updateQuery << "UPDATE alarms SET end_time = '" << newEndTime << "'" |
| | | << " WHERE id = '" << id << "'" |
| | |
| | | return m_pDB->executeQuery(updateQuery.str()); |
| | | } |
| | | |
| | | // æ¸
çæ§æ¥è¦æ°æ® |
| | | // æ¸
çæ§æ¥è¦æ°æ® |
| | | void AlarmManager::cleanOldAlarms(int daysToKeep, const std::string& deviceId, const std::string& unitId) { |
| | | if (!m_pDB) { |
| | | return; |
| | |
| | | m_pDB->executeQuery(query.str()); |
| | | } |
| | | |
| | | // éè¿è®¾å¤IDè·å设å¤åç§° |
| | | // éè¿è®¾å¤IDè·å设å¤åç§° |
| | | std::string AlarmManager::getDeviceNameById(int deviceId) { |
| | | if (!m_pDB) { |
| | | return ""; |
| | |
| | | return ""; |
| | | } |
| | | |
| | | return result[0][0]; // è¿åæ¥è¯¢å°ç设å¤åç§° |
| | | return result[0][0]; // è¿åæ¥è¯¢å°ç设å¤åç§° |
| | | } |
| | | |
| | | // éè¿è®¾å¤IDååå
IDè·ååå
åç§° |
| | | // éè¿è®¾å¤IDååå
IDè·ååå
åç§° |
| | | std::string AlarmManager::getUnitNameById(int deviceId, int unitId) { |
| | | if (!m_pDB) { |
| | | return ""; |
| | |
| | | return ""; |
| | | } |
| | | |
| | | return result[0][0]; // è¿åæ¥è¯¢å°çåå
åç§° |
| | | return result[0][0]; // è¿åæ¥è¯¢å°çåå
åç§° |
| | | } |
| | | |
| | | // è·åæè¿æå
¥ç alarm_event_id |
| | | // è·åæè¿æå
¥ç alarm_event_id |
| | | int AlarmManager::getLastInsertId() { |
| | | std::string query = "SELECT last_insert_rowid();"; |
| | | auto results = m_pDB->fetchResults(query); |
| | |
| | | return -1; |
| | | } |
| | | |
| | | // 仿¥è¯¢ç»æä¸è·åæåæå
¥ç ID |
| | | // 仿¥è¯¢ç»æä¸è·åæåæå
¥ç ID |
| | | int lastInsertId = std::stoi(results[0][0]); |
| | | return lastInsertId; |
| | | } |
| | | |
| | | // éè¿ alarm_event_id è§£é¤æ¥è¦ï¼æ´æ°ç»ææ¶é´ï¼ |
| | | // éè¿ alarm_event_id è§£é¤æ¥è¦ï¼æ´æ°ç»ææ¶é´ï¼ |
| | | bool AlarmManager::clearAlarmByEventId(int alarmEventId, const std::string& endTime) { |
| | | if (!m_pDB) { |
| | | return false; |
| | |
| | | return result; |
| | | } |
| | | |
| | | // éè¿å¤ä¸ªå±æ§æ¥æ¾å¹¶è§£é¤æ¥è¦ï¼æ´æ°ç»ææ¶é´ï¼ |
| | | // éè¿å¤ä¸ªå±æ§æ¥æ¾å¹¶è§£é¤æ¥è¦ï¼æ´æ°ç»ææ¶é´ï¼ |
| | | bool AlarmManager::clearAlarmByAttributes(int nId, int nDeviceId, int nUnitId, const std::string& endTime) { |
| | | if (!m_pDB) { |
| | | return false; |
| | |
| | | |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | |
| | | // å
å¨ç¼å䏿¥æ¾å¹é
ç alarm_event_id |
| | | // å
å¨ç¼å䏿¥æ¾å¹é
ç alarm_event_id |
| | | int alarmEventId = -1; |
| | | for (AlarmDataMap::const_iterator it = m_mapCache.begin(); it != m_mapCache.end(); ++it) { |
| | | const AlarmData& alarm = it->second; |
| | |
| | | } |
| | | } |
| | | |
| | | // å¦ææ²¡æ¾å°å¹é
çè®°å½ï¼åç´æ¥è¿å false |
| | | // ç¼åæªå½ä¸æ¶ï¼ä»æ°æ®åºæ¥æ¾ä»æªç»æçè®°å½ï¼åææ°ä¸æ¡ï¼ |
| | | if (alarmEventId == -1) { |
| | | std::ostringstream querySel; |
| | | querySel << "SELECT alarm_event_id FROM alarms WHERE " |
| | | << "id = " << nId |
| | | << " AND device_id = " << nDeviceId |
| | | << " AND unit_id = " << nUnitId |
| | | << " AND (end_time IS NULL OR end_time = '') " |
| | | << "ORDER BY start_time DESC LIMIT 1;"; |
| | | auto results = m_pDB->fetchResults(querySel.str()); |
| | | if (!results.empty() && !results[0].empty()) { |
| | | try { |
| | | alarmEventId = std::stoi(results[0][0]); |
| | | } |
| | | catch (...) { |
| | | alarmEventId = -1; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // å¦ææ²¡æ¾å°å¹é
çè®°å½ï¼åç´æ¥è¿å false |
| | | if (alarmEventId == -1) { |
| | | return false; |
| | | } |
| | | |
| | | // æå»º SQL è¯å¥ï¼ä½¿ç¨æ¾å°ç alarm_event_id æ¥æ´æ°ç»ææ¶é´ |
| | | // æå»º SQL è¯å¥ï¼ä½¿ç¨æ¾å°ç alarm_event_id æ¥æ´æ°ç»ææ¶é´ |
| | | std::ostringstream query; |
| | | query << "UPDATE alarms SET end_time = '" << endTime << "' WHERE alarm_event_id = " << alarmEventId << ";"; |
| | | bool result = m_pDB->executeQuery(query.str()); |
| | |
| | | return result; |
| | | } |
| | | |
| | | // è¯»åæ¥è¦æä»¶ |
| | | // è¯»åæ¥è¦æä»¶ |
| | | bool AlarmManager::readAlarmFile(const std::string& filename) { |
| | | std::ifstream file(filename, std::ios::binary); |
| | | if (!file.is_open()) { |
| | |
| | | char ch; |
| | | while (f.get(ch)) { |
| | | if (ch == '\r') { |
| | | // å¤ç \r\n æ åç¬ \r |
| | | // å¤ç \r\n æ åç¬ \r |
| | | if (f.peek() == '\n') f.get(); |
| | | break; |
| | | } |
| | |
| | | return true; |
| | | } |
| | | |
| | | // å°æ¥è¦æ°æ®ä¿åå°æä»¶ |
| | | // å°æ¥è¦æ°æ®ä¿åå°æä»¶ |
| | | bool AlarmManager::saveAlarmFile(const std::string& filename) { |
| | | std::ofstream file(filename); |
| | | |
| | | if (!file.is_open()) { |
| | | std::cerr << "æå¼æä»¶åå
¥å¤±è´¥!" << std::endl; |
| | | std::cerr << "æå¼æä»¶åå
¥å¤±è´¥!" << std::endl; |
| | | return false; |
| | | } |
| | | |
| | | // åå
¥æ é¢è¡ |
| | | // åå
¥æ é¢è¡ |
| | | file << "No,UNIT ID,UNIT NO,Alarm Level,Alarm Code,AlarmID,Alarm Text,Description\n"; |
| | | |
| | | // åå
¥æ¥è¦æ°æ® |
| | | // åå
¥æ¥è¦æ°æ® |
| | | int nIndex = 1; |
| | | for (const auto& pair : m_mapAlarm) { |
| | | const AlarmInfo& alarm = pair.second; |
| | |
| | | return true; |
| | | } |
| | | |
| | | // éè¿ AlarmID æ¥è¯¢å¯¹åºçæ¥è¦ä¿¡æ¯ |
| | | // éè¿ AlarmID æ¥è¯¢å¯¹åºçæ¥è¦ä¿¡æ¯ |
| | | const AlarmInfo* AlarmManager::getAlarmInfoByID(int nAlarmID) const { |
| | | auto it = m_mapAlarm.find(nAlarmID); |
| | | if (it != m_mapAlarm.end()) { |
| | | return &(it->second); |
| | | } |
| | | else { |
| | | std::cerr << "æªæ¾å° AlarmID: " << nAlarmID << std::endl; |
| | | std::cerr << "æªæ¾å° AlarmID: " << nAlarmID << std::endl; |
| | | return nullptr; |
| | | } |
| | | } |
| | | |
| | | // éè¿å¤ä¸ª AlarmID æ¥è¯¢å¯¹åºçæ¥è¦ä¿¡æ¯ |
| | | // éè¿å¤ä¸ª AlarmID æ¥è¯¢å¯¹åºçæ¥è¦ä¿¡æ¯ |
| | | std::vector<AlarmInfo> AlarmManager::getAlarmsInfoByIDs(const std::vector<int>& alarmIDs) const { |
| | | std::vector<AlarmInfo> alarms; |
| | | |
| | |
| | | alarms.push_back(it->second); |
| | | } |
| | | else { |
| | | std::cerr << "æªæ¾å° AlarmID: " << alarmID << std::endl; |
| | | std::cerr << "æªæ¾å° AlarmID: " << alarmID << std::endl; |
| | | } |
| | | } |
| | | |
| | |
| | | #ifndef ALARM_MANAGER_H |
| | | #ifndef ALARM_MANAGER_H |
| | | #define ALARM_MANAGER_H |
| | | |
| | | #include <string> |
| | |
| | | }; |
| | | |
| | | struct AlarmData { |
| | | int nId; // é误ç |
| | | int nSeverityLevel; // æ¥è¦ç级 |
| | | int nDeviceId; // 设å¤ID |
| | | int nUnitId; // åå
ID |
| | | std::string strDeviceName; // 设å¤åç§° |
| | | std::string strUnitName; // åå
åç§° |
| | | std::string strDescription; // æè¿° |
| | | std::string strStartTime; // å¼å§æ¶é´ |
| | | std::string strEndTime; // ç»ææ¶é´ |
| | | int nId; // é误ç |
| | | int nSeverityLevel; // æ¥è¦ç级 |
| | | int nDeviceId; // 设å¤ID |
| | | int nUnitId; // åå
ID |
| | | std::string strDeviceName; // 设å¤åç§° |
| | | std::string strUnitName; // åå
åç§° |
| | | std::string strDescription; // æè¿° |
| | | std::string strStartTime; // å¼å§æ¶é´ |
| | | std::string strEndTime; // ç»ææ¶é´ |
| | | }; |
| | | |
| | | using AlarmInfoMap = std::unordered_map<int, AlarmInfo>; |
| | |
| | | class AlarmManager { |
| | | public: |
| | | /** |
| | | * è·ååä¾å®ä¾ |
| | | * @return AlarmManagerå®ä¾çå¼ç¨ |
| | | * è·ååä¾å®ä¾ |
| | | * @return AlarmManagerå®ä¾çå¼ç¨ |
| | | */ |
| | | static AlarmManager& getInstance(); |
| | | |
| | | /** |
| | | * åå§åæ¥è¦è¡¨ |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | * åå§åæ¥è¦è¡¨ |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | */ |
| | | bool initAlarmTable(); |
| | | |
| | | /** |
| | | * 鿝æ¥è¦è¡¨ |
| | | * 鿝æ¥è¦è¡¨ |
| | | */ |
| | | void termAlarmTable(); |
| | | |
| | | /** |
| | | * 鿝æ¥è¦è¡¨ |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | * 鿝æ¥è¦è¡¨ |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | */ |
| | | bool destroyAlarmTable(); |
| | | |
| | | /** |
| | | * æå
¥æ¨¡ææ°æ® |
| | | * æå
¥æ¨¡ææ°æ® |
| | | */ |
| | | void insertMockData(); |
| | | |
| | | /** |
| | | * æ·»å æ¥è¦ |
| | | * @param alarmData æ¥è¦æ°æ®çç»æä½ |
| | | * @param alarmEventId æè¿æå
¥ç alarm_event_id |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | * æ·»å æ¥è¦ |
| | | * @param alarmData æ¥è¦æ°æ®çç»æä½ |
| | | * @param alarmEventId æè¿æå
¥ç alarm_event_id |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | */ |
| | | bool addAlarm(const AlarmData& alarmData, int& alarmEventId); |
| | | |
| | | /** |
| | | * æ¥è¯¢æææ¥è¦æ°æ® |
| | | * @return å
å«æææ¥è¦æ°æ®çç»æä½ |
| | | * æ¥è¯¢æææ¥è¦æ°æ® |
| | | * @return å
å«æææ¥è¦æ°æ®çç»æä½ |
| | | */ |
| | | std::vector<AlarmData> getAllAlarms(); |
| | | |
| | | /** |
| | | * æ ¹æ®æ¥è¦IDæ¥è¯¢æ¥è¦ |
| | | * @param id æ¥è¦ID |
| | | * @return å
å«çéåæ¥è¦æ°æ®çç»æä½ |
| | | * æ ¹æ®æ¥è¦IDæ¥è¯¢æ¥è¦ |
| | | * @param id æ¥è¦ID |
| | | * @return å
å«çéåæ¥è¦æ°æ®çç»æä½ |
| | | */ |
| | | std::vector<AlarmData> getAlarmsById(const std::string& id); |
| | | |
| | | /** |
| | | * æ ¹æ®æè¿°æ¥è¯¢æ¥è¦ |
| | | * @param description æ¥è¦æè¿°çç鿡件 |
| | | * @return å
å«çéåæ¥è¦æ°æ®çç»æä½ |
| | | * æ ¹æ®æè¿°æ¥è¯¢æ¥è¦ |
| | | * @param description æ¥è¦æè¿°çç鿡件 |
| | | * @return å
å«çéåæ¥è¦æ°æ®çç»æä½ |
| | | */ |
| | | std::vector<AlarmData> getAlarmsByDescription(const std::string& description); |
| | | |
| | | /** |
| | | * æ ¹æ®æ¶é´èå´æ¥è¯¢æ¥è¦ |
| | | * @param startTime èµ·å§æ¶é´ |
| | | * @param endTime ç»ææ¶é´ |
| | | * @return å
嫿¥è¯¢ç»æçæ¥è¦æ°æ® |
| | | * æ ¹æ®æ¶é´èå´æ¥è¯¢æ¥è¦ |
| | | * @param startTime èµ·å§æ¶é´ |
| | | * @param endTime ç»ææ¶é´ |
| | | * @return å
嫿¥è¯¢ç»æçæ¥è¦æ°æ® |
| | | */ |
| | | std::vector<AlarmData> getAlarmsByTimeRange(const std::string& startTime, const std::string& endTime); |
| | | |
| | | /** |
| | | * æ ¹æ®IDåæ¶é´èå´æ¥è¯¢æ¥è¦ |
| | | * @param id æ¥è¦ID |
| | | * @param startTime èµ·å§æ¶é´ |
| | | * @param endTime ç»ææ¶é´ |
| | | * @return å
嫿¥è¯¢ç»æçæ¥è¦æ°æ® |
| | | * æ ¹æ®IDåæ¶é´èå´æ¥è¯¢æ¥è¦ |
| | | * @param id æ¥è¦ID |
| | | * @param startTime èµ·å§æ¶é´ |
| | | * @param endTime ç»ææ¶é´ |
| | | * @return å
嫿¥è¯¢ç»æçæ¥è¦æ°æ® |
| | | */ |
| | | std::vector<AlarmData> getAlarmsByIdAndTimeRange(const std::string& id, const std::string& startTime, const std::string& endTime); |
| | | |
| | | /** |
| | | * è·åæ¥è¦æ°æ® |
| | | * @param startPosition èµ·å§ä½ç½® |
| | | * @param count è·åçè®°å½æ°é |
| | | * @return å
嫿¥è¯¢ç»æçæ¥è¦æ°æ® |
| | | * è·åæ¥è¦æ°æ® |
| | | * @param startPosition èµ·å§ä½ç½® |
| | | * @param count è·åçè®°å½æ°é |
| | | * @return å
嫿¥è¯¢ç»æçæ¥è¦æ°æ® |
| | | */ |
| | | std::vector<AlarmData> getAlarms(int startPosition, int count); |
| | | std::vector<AlarmData> getActiveAlarms(int recentHours = 12); |
| | | |
| | | /** |
| | | * çéæ¥è¦æ°æ® |
| | | * @param keyword å
³é®åç鿡件 |
| | | * @param startTime èµ·å§æ¶é´ç鿡件 |
| | | * @param endTime ç»ææ¶é´ç鿡件 |
| | | * @param pageNumber 页ç |
| | | * @param pageSize æ¯é¡µè®°å½æ° |
| | | * @return å
å«çéåæ¥è¦æ°æ®çç»æä½ |
| | | * çéæ¥è¦æ°æ® |
| | | * @param keyword å
³é®åç鿡件 |
| | | * @param startTime èµ·å§æ¶é´ç鿡件 |
| | | * @param endTime ç»ææ¶é´ç鿡件 |
| | | * @param pageNumber 页ç |
| | | * @param pageSize æ¯é¡µè®°å½æ° |
| | | * @return å
å«çéåæ¥è¦æ°æ®çç»æä½ |
| | | */ |
| | | std::vector<AlarmData> getFilteredAlarms(const std::string& keyword, const std::string& startTime, const std::string& endTime, int pageNumber, int pageSize); |
| | | |
| | | /** |
| | | * è·åç¬¦åæ¡ä»¶çæ¥è¦æ»æ° |
| | | * @param keyword å
³é®åç鿡件 |
| | | * @param startTime èµ·å§æ¶é´ç鿡件 |
| | | * @param endTime ç»ææ¶é´ç鿡件 |
| | | * @return ç¬¦åæ¡ä»¶çæ¥è¦æ»æ° |
| | | * è·åç¬¦åæ¡ä»¶çæ¥è¦æ»æ° |
| | | * @param keyword å
³é®åç鿡件 |
| | | * @param startTime èµ·å§æ¶é´ç鿡件 |
| | | * @param endTime ç»ææ¶é´ç鿡件 |
| | | * @return ç¬¦åæ¡ä»¶çæ¥è¦æ»æ° |
| | | */ |
| | | int getTotalAlarmCount(const std::string& keyword, const std::string& startTime, const std::string& endTime); |
| | | |
| | | /** |
| | | * æ´æ°æ¥è¦ç»ææ¶é´ |
| | | * @param id æ¥è¦ID |
| | | * @param severityLevel æ¥è¦ç级ç鿡件 |
| | | * @param deviceId 设å¤ID |
| | | * @param unitId åå
ID |
| | | * @param description æ¥è¦æè¿° |
| | | * @param startTime æ¥è¦å¼å§æ¶é´ |
| | | * @param newEndTime æ°çæ¥è¦ç»ææ¶é´ |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | * æ´æ°æ¥è¦ç»ææ¶é´ |
| | | * @param id æ¥è¦ID |
| | | * @param severityLevel æ¥è¦ç级ç鿡件 |
| | | * @param deviceId 设å¤ID |
| | | * @param unitId åå
ID |
| | | * @param description æ¥è¦æè¿° |
| | | * @param startTime æ¥è¦å¼å§æ¶é´ |
| | | * @param newEndTime æ°çæ¥è¦ç»ææ¶é´ |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | */ |
| | | bool updateAlarmEndTime( |
| | | const std::string& id, |
| | |
| | | const std::string& newEndTime); |
| | | |
| | | /** |
| | | * æ¸
çæ§æ¥è¦ |
| | | * @param daysToKeep ä¿ççå¤©æ° |
| | | * @param deviceId 设å¤ID |
| | | * @param unitId åå
ID |
| | | * æ¸
çæ§æ¥è¦ |
| | | * @param daysToKeep ä¿ççå¤©æ° |
| | | * @param deviceId 设å¤ID |
| | | * @param unitId åå
ID |
| | | */ |
| | | void cleanOldAlarms(int daysToKeep = 30, const std::string& deviceId = "", const std::string& unitId = ""); |
| | | |
| | | /** |
| | | * éè¿è®¾å¤IDè·å设å¤åç§° |
| | | * @param deviceId 设å¤ID |
| | | * @return æåè¿å设å¤åç§°ï¼å¤±è´¥è¿å空 |
| | | * éè¿è®¾å¤IDè·å设å¤åç§° |
| | | * @param deviceId 设å¤ID |
| | | * @return æåè¿å设å¤åç§°ï¼å¤±è´¥è¿å空 |
| | | */ |
| | | std::string getDeviceNameById(int deviceId); |
| | | |
| | | /** |
| | | * éè¿è®¾å¤IDååå
IDè·ååå
åç§° |
| | | * @param deviceId 设å¤ID |
| | | * @param unitId åå
ID |
| | | * @return æåè¿ååå
åç§°ï¼å¤±è´¥è¿å空 |
| | | * éè¿è®¾å¤IDååå
IDè·ååå
åç§° |
| | | * @param deviceId 设å¤ID |
| | | * @param unitId åå
ID |
| | | * @return æåè¿ååå
åç§°ï¼å¤±è´¥è¿å空 |
| | | */ |
| | | std::string getUnitNameById(int deviceId, int unitId); |
| | | |
| | | /** |
| | | * è·åæè¿æå
¥ç alarm_event_id |
| | | * @return 失败è¿å-1ï¼æåè¿åæè¿æå
¥ç alarm_event_id |
| | | * è·åæè¿æå
¥ç alarm_event_id |
| | | * @return 失败è¿å-1ï¼æåè¿åæè¿æå
¥ç alarm_event_id |
| | | */ |
| | | int getLastInsertId(); |
| | | |
| | | /** |
| | | * éè¿äºä»¶idè§£é¤æ¥è¦ï¼æ´æ°ç»ææ¶é´ï¼ |
| | | * @param alarmEventId äºä»¶ID |
| | | * @param endTime ç»ææ¶é´ |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | * éè¿äºä»¶idè§£é¤æ¥è¦ï¼æ´æ°ç»ææ¶é´ï¼ |
| | | * @param alarmEventId äºä»¶ID |
| | | * @param endTime ç»ææ¶é´ |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | */ |
| | | bool clearAlarmByEventId(int alarmEventId, const std::string& endTime); |
| | | |
| | | /** |
| | | * éè¿å¤ä¸ªå±æ§æ¥æ¾å¹¶è§£é¤æ¥è¦ï¼æ´æ°ç»ææ¶é´ï¼ |
| | | * @param nId æ¥è¦ID |
| | | * @param nSeverityLevel æ¥è¦ç级 |
| | | * @param nDeviceId 设å¤ID |
| | | * @param nUnitId åå
ID |
| | | * @param strDescription æè¿° |
| | | * @param endTime ç»ææ¶é´ |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | * éè¿å¤ä¸ªå±æ§æ¥æ¾å¹¶è§£é¤æ¥è¦ï¼æ´æ°ç»ææ¶é´ï¼ |
| | | * @param nId æ¥è¦ID |
| | | * @param nSeverityLevel æ¥è¦ç级 |
| | | * @param nDeviceId 设å¤ID |
| | | * @param nUnitId åå
ID |
| | | * @param strDescription æè¿° |
| | | * @param endTime ç»ææ¶é´ |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | */ |
| | | bool clearAlarmByAttributes(int nId, int nDeviceId, int nUnitId, const std::string& endTime); |
| | | |
| | | /** |
| | | * è¯»åæ¥è¦æä»¶ |
| | | * @param filename æä»¶å |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | * è¯»åæ¥è¦æä»¶ |
| | | * @param filename æä»¶å |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | */ |
| | | bool readAlarmFile(const std::string& filename); |
| | | |
| | | /** |
| | | * ä¿åæ¥è¦æä»¶ |
| | | * @param filename æä»¶å |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | * ä¿åæ¥è¦æä»¶ |
| | | * @param filename æä»¶å |
| | | * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse |
| | | */ |
| | | bool saveAlarmFile(const std::string& filename); |
| | | |
| | | /** |
| | | * éè¿æ¥è¦IDæ¥è¯¢æ¥è¦ä¿¡æ¯ |
| | | * @param nAlarmID æ¥è¦ID |
| | | * @return æ¥è¦ä¿¡æ¯çæé |
| | | * éè¿æ¥è¦IDæ¥è¯¢æ¥è¦ä¿¡æ¯ |
| | | * @param nAlarmID æ¥è¦ID |
| | | * @return æ¥è¦ä¿¡æ¯çæé |
| | | */ |
| | | const AlarmInfo* getAlarmInfoByID(int nAlarmID) const; |
| | | |
| | | /** |
| | | * éè¿å¤ä¸ªæ¥è¦IDæ¥è¯¢å¯¹åºçæ¥è¦ä¿¡æ¯ |
| | | * @param alarmIDs å¤ä¸ªæ¥è¦ID |
| | | * @return è¿åå¤ä¸ªæ¥è¦ä¿¡æ¯ |
| | | * éè¿å¤ä¸ªæ¥è¦IDæ¥è¯¢å¯¹åºçæ¥è¦ä¿¡æ¯ |
| | | * @param alarmIDs å¤ä¸ªæ¥è¦ID |
| | | * @return è¿åå¤ä¸ªæ¥è¦ä¿¡æ¯ |
| | | */ |
| | | std::vector<AlarmInfo> getAlarmsInfoByIDs(const std::vector<int>& alarmIDs) const; |
| | | |
| | |
| | | AlarmManager(); |
| | | ~AlarmManager(); |
| | | |
| | | // ç¦æ¢æ·è´åèµå¼ |
| | | // ç¦æ¢æ·è´åèµå¼ |
| | | AlarmManager(const AlarmManager&) = delete; |
| | | AlarmManager& operator=(const AlarmManager&) = delete; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "AlarmPopupDlg.h" |
| | | #include "afxdialogex.h" |
| | | #include "Log.h" |
| | | #include "Common.h" |
| | | #include "HorizontalLine.h" |
| | | #include "ServoDlg.h" |
| | | |
| | | |
| | | IMPLEMENT_DYNAMIC(CAlarmPopupDlg, CDialogEx) |
| | | |
| | | CAlarmPopupDlg::CAlarmPopupDlg(CWnd* pParent /*=NULL*/) |
| | | : CDialogEx(IDD_DIALOG_POPUP_ALARM, pParent) |
| | | , m_hasActive(false) |
| | | { |
| | | memset(&m_activeAlarm, 0, sizeof(m_activeAlarm)); |
| | | m_crBkgnd = RGB(112, 146, 190); |
| | | m_hbrBkgnd = nullptr; |
| | | } |
| | | |
| | | CAlarmPopupDlg::~CAlarmPopupDlg() |
| | | { |
| | | } |
| | | |
| | | void CAlarmPopupDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CAlarmPopupDlg, CDialogEx) |
| | | ON_BN_CLICKED(IDC_POPUP_BTN_CLOSE, &CAlarmPopupDlg::OnBnClickedClose) |
| | | ON_BN_CLICKED(IDC_BUTTON_ALARM_OFF, &CAlarmPopupDlg::OnBnClickedAlarmOff) |
| | | ON_BN_CLICKED(IDC_BUTTON_PREV, &CAlarmPopupDlg::OnBnClickedPrev) |
| | | ON_BN_CLICKED(IDC_BUTTON_NEXT, &CAlarmPopupDlg::OnBnClickedNext) |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_DESTROY() |
| | | END_MESSAGE_MAP() |
| | | |
| | | BOOL CAlarmPopupDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | // èæ¯å· |
| | | if (m_hbrBkgnd != nullptr) { |
| | | ::DeleteObject(m_hbrBkgnd); |
| | | } |
| | | m_hbrBkgnd = CreateSolidBrush(m_crBkgnd); |
| | | |
| | | // åä½ |
| | | HFONT hFontDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT); |
| | | LOGFONT lf; |
| | | |
| | | ::GetObject(hFontDefault, sizeof(LOGFONT), &lf); |
| | | lf.lfHeight -= 8; |
| | | lf.lfWeight = 700; |
| | | m_fontTitle.CreateFontIndirect(&lf); |
| | | |
| | | ::GetObject(hFontDefault, sizeof(LOGFONT), &lf); |
| | | lf.lfHeight -= 8; |
| | | m_fontLevel.CreateFontIndirect(&lf); |
| | | |
| | | ::GetObject(hFontDefault, sizeof(LOGFONT), &lf); |
| | | lf.lfHeight -= 16; |
| | | m_fontName.CreateFontIndirect(&lf); |
| | | |
| | | ::GetObject(hFontDefault, sizeof(LOGFONT), &lf); |
| | | lf.lfHeight -= 8; |
| | | m_fontDescription.CreateFontIndirect(&lf); |
| | | |
| | | GetDlgItem(IDC_LABEL_TITLE)->SetFont(&m_fontTitle); |
| | | GetDlgItem(IDC_LABEL_LEVEL)->SetFont(&m_fontLevel); |
| | | GetDlgItem(IDC_LABEL_NAME)->SetFont(&m_fontName); |
| | | GetDlgItem(IDC_LABEL_DESCRIPTION)->SetFont(&m_fontDescription); |
| | | GetDlgItem(IDC_LABEL_NO_ALARM)->SetFont(&m_fontDescription); |
| | | |
| | | |
| | | // 徿 |
| | | CString strIcon1; |
| | | HICON hIcon; |
| | | CStatic* pStatic; |
| | | |
| | | strIcon1.Format(_T("%s\\Res\\Alarm_o_24.ico"), theApp.m_strAppDir); |
| | | pStatic = (CStatic*)GetDlgItem(IDC_ICON_TITLE); |
| | | hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(), |
| | | strIcon1, IMAGE_ICON, 24, 24, |
| | | LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); |
| | | pStatic->SetIcon(hIcon); |
| | | |
| | | strIcon1.Format(_T("%s\\Res\\Alarm_o_64.ico"), theApp.m_strAppDir); |
| | | pStatic = (CStatic*)GetDlgItem(IDC_ICON_ALARM); |
| | | hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(), |
| | | strIcon1, IMAGE_ICON, 64, 64, |
| | | LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); |
| | | pStatic->SetIcon(hIcon); |
| | | |
| | | |
| | | // å
³éæé® |
| | | strIcon1.Format(_T("%s\\Res\\close_blcak_24.ico"), theApp.m_strAppDir); |
| | | pStatic = (CStatic*)GetDlgItem(IDC_ICON_ALARM); |
| | | hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(), |
| | | strIcon1, IMAGE_ICON, 128, 128, |
| | | LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); |
| | | m_btnClose.SubclassDlgItem(IDC_POPUP_BTN_CLOSE, this); |
| | | m_btnClose.SetIcon(hIcon, hIcon, 24); |
| | | m_btnClose.SetFaceColor(m_crBkgnd); |
| | | m_btnClose.SetBkgndColor(BS_NORMAL, BTN_ALARM_OFF_BKGND_NORMAL); |
| | | m_btnClose.SetBkgndColor(BS_HOVER, BTN_ALARM_OFF_BKGND_NORMAL); |
| | | m_btnClose.SetBkgndColor(BS_PRESS, BTN_ALARM_OFF_BKGND_PRESS); |
| | | m_btnClose.SetFrameColor(m_crBkgnd); |
| | | |
| | | |
| | | // è§£é¤è¦åæé® |
| | | m_btnAlarmOff.SubclassDlgItem(IDC_BUTTON_ALARM_OFF, this); |
| | | m_btnAlarmOff.SetFrameColor(BS_NORMAL, BTN_ALARM_OFF_FRAME_NORMAL); |
| | | m_btnAlarmOff.SetFrameColor(BS_HOVER, BTN_ALARM_OFF_FRAME_HOVER); |
| | | m_btnAlarmOff.SetFrameColor(BS_PRESS, BTN_ALARM_OFF_FRAME_PRESS); |
| | | m_btnAlarmOff.SetBkgndColor(BS_NORMAL, BTN_ALARM_OFF_BKGND_NORMAL); |
| | | m_btnAlarmOff.SetBkgndColor(BS_HOVER, BTN_ALARM_OFF_BKGND_HOVER); |
| | | m_btnAlarmOff.SetBkgndColor(BS_PRESS, BTN_ALARM_OFF_BKGND_PRESS); |
| | | |
| | | |
| | | // éé³æé® |
| | | bool bMute = false; |
| | | m_btnSoundOff.SubclassDlgItem(IDC_BUTTON_SOUND_OFF, this); |
| | | m_btnSoundOff.SetFrameColor(BS_NORMAL, BTN_SOUND_OFF_FRAME_NORMAL); |
| | | m_btnSoundOff.SetFrameColor(BS_HOVER, BTN_SOUND_OFF_FRAME_HOVER); |
| | | m_btnSoundOff.SetFrameColor(BS_PRESS, BTN_SOUND_OFF_FRAME_PRESS); |
| | | SetButtonBackgroundColors(bMute); |
| | | |
| | | // 横线1 |
| | | CHorizontalLine* pLine = CHorizontalLine::Hook(GetDlgItem(IDC_LINE1)->m_hWnd); |
| | | pLine->SetBkgndColor(m_crBkgnd); |
| | | pLine->SetLineColor(RGB(168, 168, 168)); |
| | | |
| | | pLine = CHorizontalLine::Hook(GetDlgItem(IDC_LINE2)->m_hWnd); |
| | | pLine->SetBkgndColor(m_crBkgnd); |
| | | pLine->SetLineColor(RGB(168, 168, 168)); |
| | | |
| | | RefreshContent(); |
| | | return TRUE; |
| | | } |
| | | |
| | | void CAlarmPopupDlg::ShowNoAlarmControls(bool bShow) |
| | | { |
| | | const int ids[] = { IDC_LABEL_NO_ALARM }; |
| | | for (int id : ids) { |
| | | if (auto* p = GetDlgItem(id)) { |
| | | p->ShowWindow(bShow ? SW_SHOW : SW_HIDE); |
| | | } |
| | | } |
| | | } |
| | | |
| | | void CAlarmPopupDlg::ShowAlarmControls(bool bShow) |
| | | { |
| | | const int ids[] = { |
| | | IDC_BUTTON_PREV, IDC_BUTTON_NEXT, |
| | | IDC_LABEL_TITLE, IDC_ICON_ALARM, IDC_ICON_TITLE, |
| | | IDC_LABEL_LEVEL, IDC_LABEL_NAME, |
| | | IDC_LINE1, IDC_BUTTON_SOUND_OFF, IDC_BUTTON_ALARM_OFF, |
| | | IDC_LINE2, IDC_LABEL_DESCRIPTION |
| | | }; |
| | | for (int id : ids) { |
| | | if (auto* p = GetDlgItem(id)) { |
| | | p->ShowWindow(bShow ? SW_SHOW : SW_HIDE); |
| | | } |
| | | } |
| | | } |
| | | |
| | | void CAlarmPopupDlg::RefreshContent() |
| | | { |
| | | m_activeAlarms = AlarmManager::getInstance().getActiveAlarms(); |
| | | m_activeIndex = 0; |
| | | |
| | | if (!m_activeAlarms.empty()) { |
| | | m_hasActive = true; |
| | | DisplayActiveAt(m_activeIndex); |
| | | ShowAlarmControls(true); |
| | | ShowNoAlarmControls(false); |
| | | } |
| | | else { |
| | | m_hasActive = false; |
| | | SetDlgItemText(IDC_LABEL_NO_ALARM, _T("å½åæ æ¥è¦")); |
| | | SetDlgItemText(IDC_LABEL_NAME, _T("")); |
| | | SetDlgItemText(IDC_LABEL_LEVEL, _T("")); |
| | | SetDlgItemText(IDC_LABEL_DESCRIPTION, _T("")); |
| | | ShowAlarmControls(false); |
| | | ShowNoAlarmControls(true); |
| | | } |
| | | } |
| | | |
| | | void CAlarmPopupDlg::OnBnClickedClose() |
| | | { |
| | | ShowWindow(SW_HIDE); |
| | | } |
| | | |
| | | void CAlarmPopupDlg::OnBnClickedAlarmOff() |
| | | { |
| | | if (!m_hasActive) return; |
| | | |
| | | AlarmManager& alarmManager = AlarmManager::getInstance(); |
| | | alarmManager.clearAlarmByAttributes( |
| | | m_activeAlarm.nId, |
| | | m_activeAlarm.nDeviceId, |
| | | m_activeAlarm.nUnitId, |
| | | CToolUnits::getCurrentTimeString()); |
| | | RefreshContent(); |
| | | } |
| | | |
| | | void CAlarmPopupDlg::OnBnClickedPrev() |
| | | { |
| | | if (m_activeIndex > 0) { |
| | | --m_activeIndex; |
| | | DisplayActiveAt(m_activeIndex); |
| | | } |
| | | } |
| | | |
| | | void CAlarmPopupDlg::OnBnClickedNext() |
| | | { |
| | | if (m_activeIndex + 1 < static_cast<int>(m_activeAlarms.size())) { |
| | | ++m_activeIndex; |
| | | DisplayActiveAt(m_activeIndex); |
| | | } |
| | | } |
| | | |
| | | void CAlarmPopupDlg::DisplayActiveAt(int idx) |
| | | { |
| | | if (idx < 0 || idx >= static_cast<int>(m_activeAlarms.size())) return; |
| | | |
| | | m_activeAlarm = m_activeAlarms[idx]; |
| | | |
| | | // æ 记已读 |
| | | if (auto* pParent = dynamic_cast<CServoDlg*>(GetParent())) { |
| | | pParent->AckAlarm(m_activeAlarm.nId); |
| | | } |
| | | |
| | | AlarmManager& alarmManager = AlarmManager::getInstance(); |
| | | const AlarmInfo* info = alarmManager.getAlarmInfoByID(m_activeAlarm.nId); |
| | | |
| | | CString title, level, name, desc; |
| | | level.Format(_T("ç级: %d"), m_activeAlarm.nSeverityLevel); |
| | | |
| | | if (info != nullptr && !info->strAlarmText.empty()) { |
| | | name = CString(info->strAlarmText.c_str()); |
| | | } |
| | | else { |
| | | name.Format(_T("ID:%d (%s)"), m_activeAlarm.nId, CString(m_activeAlarm.strDeviceName.c_str())); |
| | | } |
| | | |
| | | if (!m_activeAlarm.strDescription.empty()) { |
| | | desc = CString(m_activeAlarm.strDescription.c_str()); |
| | | } |
| | | else if (info != nullptr && !info->strDescription.empty()) { |
| | | desc = CString(info->strDescription.c_str()); |
| | | } |
| | | else { |
| | | desc = _T("ææ æè¿°"); |
| | | } |
| | | |
| | | title.Format(_T("设å¤:%s åå
:%s"), |
| | | CString(m_activeAlarm.strDeviceName.c_str()), |
| | | CString(m_activeAlarm.strUnitName.c_str())); |
| | | |
| | | SetDlgItemText(IDC_LABEL_TITLE, title); |
| | | SetDlgItemText(IDC_LABEL_NAME, name); |
| | | SetDlgItemText(IDC_LABEL_LEVEL, level); |
| | | SetDlgItemText(IDC_LABEL_DESCRIPTION, desc); |
| | | |
| | | UpdateNavButtons(); |
| | | ShowWindow(SW_SHOW); |
| | | } |
| | | |
| | | void CAlarmPopupDlg::UpdateNavButtons() |
| | | { |
| | | auto* pPrev = GetDlgItem(IDC_BUTTON_PREV); |
| | | auto* pNext = GetDlgItem(IDC_BUTTON_NEXT); |
| | | if (pPrev) pPrev->EnableWindow(m_activeIndex > 0); |
| | | if (pNext) pNext->EnableWindow(m_activeIndex + 1 < static_cast<int>(m_activeAlarms.size())); |
| | | } |
| | | |
| | | HBRUSH CAlarmPopupDlg::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(30, 30, 30)); |
| | | hbr = m_hbrBkgnd; |
| | | } |
| | | else if (nCtlColor == CTLCOLOR_DLG) { |
| | | hbr = m_hbrBkgnd; |
| | | } |
| | | |
| | | return hbr; |
| | | } |
| | | |
| | | void CAlarmPopupDlg::OnDestroy() |
| | | { |
| | | CDialogEx::OnDestroy(); |
| | | |
| | | if (m_hbrBkgnd != nullptr) { |
| | | ::DeleteObject(m_hbrBkgnd); |
| | | m_hbrBkgnd = nullptr; |
| | | } |
| | | } |
| | | |
| | | void CAlarmPopupDlg::SetButtonBackgroundColors(bool bMute) |
| | | { |
| | | if (!bMute) { |
| | | m_btnSoundOff.SetBkgndColor(BS_NORMAL, BTN_SOUND_OFF_BKGND_NORMAL); |
| | | m_btnSoundOff.SetBkgndColor(BS_HOVER, BTN_SOUND_OFF_BKGND_HOVER); |
| | | m_btnSoundOff.SetBkgndColor(BS_PRESS, BTN_SOUND_OFF_BKGND_PRESS); |
| | | m_btnSoundOff.Invalidate(); |
| | | } |
| | | else { |
| | | m_btnSoundOff.SetBkgndColor(BS_NORMAL, BTN_SOUND_ON_BKGND_NORMAL); |
| | | m_btnSoundOff.SetBkgndColor(BS_HOVER, BTN_SOUND_ON_BKGND_HOVER); |
| | | m_btnSoundOff.SetBkgndColor(BS_PRESS, BTN_SOUND_ON_BKGND_PRESS); |
| | | m_btnSoundOff.Invalidate(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxwin.h" |
| | | #include "AlarmManager.h" |
| | | #include "Common.h" |
| | | #include "ToolUnits.h" |
| | | #include "BlButton.h" |
| | | |
| | | // ç®åçæ¥è¦å¼¹çªï¼å¯¹æ¥ AlarmManager çæ´»è·åè¦ |
| | | class CAlarmPopupDlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CAlarmPopupDlg) |
| | | |
| | | public: |
| | | CAlarmPopupDlg(CWnd* pParent = NULL); |
| | | virtual ~CAlarmPopupDlg(); |
| | | |
| | | public: |
| | | void RefreshContent(); // å·æ°å½ååè¦æ¾ç¤º |
| | | |
| | | private: |
| | | COLORREF m_crBkgnd; |
| | | HBRUSH m_hbrBkgnd; |
| | | CFont m_fontTitle; |
| | | CFont m_fontLevel; |
| | | CFont m_fontName; |
| | | CFont m_fontDescription; |
| | | CBlButton m_btnClose; |
| | | CBlButton m_btnSoundOff; |
| | | CBlButton m_btnAlarmOff; |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_POPUP_ALARM }; |
| | | #endif |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); |
| | | afx_msg void OnDestroy(); |
| | | afx_msg void OnBnClickedClose(); |
| | | afx_msg void OnBnClickedAlarmOff(); |
| | | afx_msg void OnBnClickedPrev(); |
| | | afx_msg void OnBnClickedNext(); |
| | | |
| | | private: |
| | | bool m_hasActive; |
| | | AlarmData m_activeAlarm; |
| | | std::vector<AlarmData> m_activeAlarms; |
| | | int m_activeIndex = 0; |
| | | void SetButtonBackgroundColors(bool bMute); |
| | | void ShowNoAlarmControls(bool bShow); |
| | | void ShowAlarmControls(bool bShow); |
| | | void UpdateNavButtons(); |
| | | void DisplayActiveAt(int idx); |
| | | }; |
| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "CBonder.h" |
| | | |
| | | |
| | |
| | | CEquipment::term(); |
| | | } |
| | | |
| | | // å¿
é¡»è¦å®ç°çè彿°ï¼å¨æ¤åå§åPinå表 |
| | | // å¿
é¡»è¦å®ç°çè彿°ï¼å¨æ¤åå§åPinå表 |
| | | void CBonder::initPins() |
| | | { |
| | | // å å
¥Pinåå§å代ç |
| | | // å å
¥Pinåå§å代ç |
| | | LOGI("<CBonder>initPins"); |
| | | addPin(SERVO::PinType::INPUT, _T("In1")); |
| | | addPin(SERVO::PinType::INPUT, _T("In2")); |
| | |
| | | |
| | | { |
| | | // CIM Message Confirm |
| | | // è¦å°int32ç弿å为两个short, åå«ä¸ºmsg idåpanel id |
| | | // 65538, 2Ϊmsg id, 1Ϊpanel id |
| | | // è¦å°int32ç弿å为两个short, åå«ä¸ºmsg idåpanel id |
| | | // 65538, 2为msg id, 1为panel id |
| | | CEqReadIntStep* pStep = new CEqReadIntStep(__INT32, m_nIndex == 0 ? 0x9d80 : 0xdd80); |
| | | pStep->setName(STEP_EQ_CIM_MESSAGE_CONFIRM); |
| | | pStep->setWriteSignalDev(m_nIndex == 0 ? 0x349 : 0x649); |
| | |
| | | } |
| | | |
| | | { |
| | | // 请æ±ä¸»é
æ¹å表çstep |
| | | // 请æ±ä¸»é
æ¹å表çstep |
| | | CEqWriteStep* pStep = new CEqWriteStep(); |
| | | pStep->setName(STEP_EQ_MASTER_RECIPE_LIST_REQ); |
| | | pStep->setWriteSignalDev(m_nIndex == 0 ? 0x366 : 0x666); |
| | |
| | | CEqReadStep* pTmpStep = (CEqReadStep*)pFrom; |
| | | short ret = MRLRC_OK; |
| | | if (code == ROK && pszData != nullptr && size > 0) { |
| | | // æ¤å¤è§£éé
æ¹æ°æ® |
| | | // æ¤å¤è§£éé
æ¹æ°æ® |
| | | ret = decodeRecipeListReport(pszData, size); |
| | | } |
| | | pTmpStep->setReturnCode(ret); |
| | |
| | | } |
| | | |
| | | { |
| | | // 请æ±é
æ¹åæ° |
| | | // 请æ±é
æ¹åæ° |
| | | CEqWriteStep* pStep = new CEqWriteStep(); |
| | | pStep->setName(STEP_EQ_RECIPE_PARAMETER_REQ); |
| | | pStep->setWriteSignalDev(m_nIndex == 0 ? 0x367 : 0x667); |
| | |
| | | CEqReadStep* pTmpStep = (CEqReadStep*)pFrom; |
| | | short ret = MRLRC_OK; |
| | | if (code == ROK && pszData != nullptr && size > 0) { |
| | | // æ¤å¤è§£éé
æ¹æ°æ® |
| | | // æ¤å¤è§£éé
æ¹æ°æ® |
| | | ret = decodeRecipeParameterReport(pszData, size); |
| | | } |
| | | pTmpStep->setReturnCode(ret); |
| | |
| | | } |
| | | } |
| | | |
| | | // 使ç¨CEqReadStepæ¿æ¢CEqJobEventStep |
| | | // 使ç¨CEqReadStepæ¿æ¢CEqJobEventStep |
| | | { |
| | | // Received Job Report Upstream #1~9 |
| | | char szBuffer[256]; |
| | |
| | | } |
| | | } |
| | | |
| | | // å¿
é¡»è¦å®ç°çè彿°ï¼å¨æ¤åå§åSlotä¿¡æ¯ |
| | | // å¿
é¡»è¦å®ç°çè彿°ï¼å¨æ¤åå§åSlotä¿¡æ¯ |
| | | void CBonder::initSlots() |
| | | { |
| | | m_slot[0].enable(); |
| | |
| | | return 0; |
| | | } |
| | | |
| | | int CBonder::onProcessStateChanged(int slotNo, PROCESS_STATE state) |
| | | int CBonder::onProcessStateChanged(int slotNo, PROCESS_STATE prevState, PROCESS_STATE state) |
| | | { |
| | | CEquipment::onProcessStateChanged(slotNo, state); |
| | | CEquipment::onProcessStateChanged(slotNo, prevState, state); |
| | | |
| | | if (state == PROCESS_STATE::Complete) { |
| | | // æ£æ¥æ°æ®ï¼å½å两çç»çï¼ä¸ç为G1, ä¸ç为G2, ä¸pProcessDataä¸çidè½å¹é
G1æG2 |
| | | // æ£æ¥æ°æ®ï¼å½å两çç»çï¼ä¸ç为G1, ä¸ç为G2, ä¸pProcessDataä¸çidè½å¹é
G1æG2 |
| | | Lock(); |
| | | CGlass* pGlass2 = getGlassFromSlot(1); |
| | | CGlass* pGlass1 = getGlassFromSlot(2); |
| | | if (pGlass1 == nullptr || pGlass2 == nullptr) { |
| | | LOGE("<CBonder-%s>onProcessData,é误!䏿»¡è¶³ä¸¤çç»çä¸åå«ä¸ºG1ä¸G2çæ¡ä»¶ï¼è¯·æ£æ¥æ°æ®æ¯å¦æ£ç¡®!", m_strName.c_str()); |
| | | LOGE("<CBonder-%s>onProcessData,é误!䏿»¡è¶³ä¸¤çç»çä¸åå«ä¸ºG1ä¸G2çæ¡ä»¶ï¼è¯·æ£æ¥æ°æ®æ¯å¦æ£ç¡®!", m_strName.c_str()); |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | if (pGlass1->getBuddy() != nullptr) { |
| | | LOGE("<CBonder-%s>onProcessData,é误!ç»çè¾æ©å已被ç»å®ï¼è¯·æ£æ¥æ°æ®æ¯å¦æ£ç¡®!", m_strName.c_str()); |
| | | LOGE("<CBonder-%s>onProcessData,é误!ç»çè¾æ©å已被ç»å®ï¼è¯·æ£æ¥æ°æ®æ¯å¦æ£ç¡®!", m_strName.c_str()); |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | |
| | | if (pGlass1->getType() != MaterialsType::G1 || pGlass2->getType() != MaterialsType::G2) { |
| | | LOGE("<CBonder-%s>onProcessData,é误!两çç»çæªå¹é
ï¼å¿
é¡»åå«ä¸ºG1åG2ç±»åï¼è¯·æ£æ¥æ°æ®æ¯å¦æ£ç¡®!", m_strName.c_str()); |
| | | LOGE("<CBonder-%s>onProcessData,é误!两çç»çæªå¹é
ï¼å¿
é¡»åå«ä¸ºG1åG2ç±»åï¼è¯·æ£æ¥æ°æ®æ¯å¦æ£ç¡®!", m_strName.c_str()); |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | |
| | | pGlass1->setBuddy(pGlass2); |
| | | getSlot(0)->setContext(nullptr); |
| | | LOGE("<CBonder-%s>onProcessStateChanged,%så%s已贴å!", m_strName.c_str(), |
| | | LOGE("<CBonder-%s>onProcessStateChanged,%så%s已贴å!", m_strName.c_str(), |
| | | pGlass1->getID().c_str(), pGlass2->getID().c_str()); |
| | | Unlock(); |
| | | } |
| | |
| | | int i = 0, v; |
| | | |
| | | |
| | | // 1.æ ¡æ£å¯¹ä½å»¶æ¶ |
| | | // 1.æ ¡æ£å¯¹ä½å»¶æ¶ |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("æ ¡æ£å¯¹ä½å»¶æ¶", "", this->getName().c_str(), v * 0.01f)); |
| | | params.push_back(CParam("æ ¡æ£å¯¹ä½å»¶æ¶", "", this->getName().c_str(), v * 0.01f)); |
| | | i += 2; |
| | | |
| | | // 2.ä¿åæ¶é´ |
| | | // 2.ä¿åæ¶é´ |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¿åæ¶é´", "", this->getName().c_str(), v * 0.01f)); |
| | | params.push_back(CParam("ä¿åæ¶é´", "", this->getName().c_str(), v * 0.01f)); |
| | | i += 2; |
| | | |
| | | // 3.è
ä½ç ´çç©ºå»¶æ¶ |
| | | // 3.è
ä½ç ´çç©ºå»¶æ¶ |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("è
ä½ç ´ç空延æ¶", "", this->getName().c_str(), v * 0.01f)); |
| | | params.push_back(CParam("è
ä½ç ´ç空延æ¶", "", this->getName().c_str(), v * 0.01f)); |
| | | i += 2; |
| | | |
| | | // 4.è
ä½ååæ³µå¯å¨å»¶æ¶ |
| | | // 4.è
ä½ååæ³µå¯å¨å»¶æ¶ |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("è
ä½ååæ³µå¯å¨å»¶æ¶", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("è
ä½ååæ³µå¯å¨å»¶æ¶", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 5.è
ä½è´´éæ½çç©ºå»¶æ¶ |
| | | // 5.è
ä½è´´éæ½çç©ºå»¶æ¶ |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("è
ä½è´´éæ½ç空延æ¶", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("è
ä½è´´éæ½ç空延æ¶", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 6.å ççå¾
å»¶æ¶ |
| | | // 6.å ççå¾
å»¶æ¶ |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("å ççå¾
å»¶æ¶", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("å ççå¾
å»¶æ¶", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 7.æ°åååè®¾å® |
| | | // 7.æ°åååè®¾å® |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("æ°ååå设å®", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("æ°ååå设å®", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 8.æ°åå åéç |
| | | // 8.æ°åå åéç |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("æ°åå åéç", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("æ°åå åéç", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 9.æ°åæ³åéç |
| | | // 9.æ°åæ³åéç |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("æ°åæ³åéç", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("æ°åæ³åéç", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 10.è´´éååä¸é |
| | | // 10.è´´éååä¸é |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("è´´éååä¸é", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("è´´éååä¸é", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 4; |
| | | |
| | | // 11.Z轴转ç©éåº¦è®¾å® |
| | | // 11.Z轴转ç©éåº¦è®¾å® |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("ä¸è
Z轴转ç©é度设å®", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("ä¸è
Z轴转ç©é度设å®", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 12.ä¸è
æ¸©åº¦è®¾å® |
| | | // 12.ä¸è
æ¸©åº¦è®¾å® |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度设å®", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度设å®", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 13.ä¸è
æ¸©åº¦è®¾å® |
| | | // 13.ä¸è
æ¸©åº¦è®¾å® |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度设å®", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度设å®", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 14.ä¸è
Zè½´é¢è´´åä½é度 |
| | | // 14.ä¸è
Zè½´é¢è´´åä½é度 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("ä¸è
Zè½´é¢è´´åä½é度", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("ä¸è
Zè½´é¢è´´åä½é度", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 15.ä¸è
Zè½´è´´éä½é度 |
| | | // 15.ä¸è
Zè½´è´´éä½é度 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("ä¸è
Zè½´è´´éä½é度", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("ä¸è
Zè½´è´´éä½é度", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 16.ä¸è
Zä¸è
å çä½é´è· |
| | | // 16.ä¸è
Zä¸è
å çä½é´è· |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("ä¸è
Zä¸è
å çä½é´è·", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("ä¸è
Zä¸è
å çä½é´è·", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 17.ä¸è
è´´éä½åå
¥é |
| | | // 17.ä¸è
è´´éä½åå
¥é |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("ä¸è
è´´éä½åå
¥é", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("ä¸è
è´´éä½åå
¥é", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 18.ä¸è
Zè½´ç ´ç空è·ç¦» |
| | | // 18.ä¸è
Zè½´ç ´ç空è·ç¦» |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("ä¸è
Zè½´ç ´ç空è·ç¦»", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("ä¸è
Zè½´ç ´ç空è·ç¦»", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 19.ä¸é¡¶Pinç ´ç空è·ç¦» |
| | | // 19.ä¸é¡¶Pinç ´ç空è·ç¦» |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("ä¸é¡¶Pinç ´ç空è·ç¦»", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("ä¸é¡¶Pinç ´ç空è·ç¦»", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 20.ä¸é¡¶Pinå çä½é´è· |
| | | // 20.ä¸é¡¶Pinå çä½é´è· |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("ä¸é¡¶Pinå çä½é´è·", "", this->getName().c_str(), v * 0.001f)); |
| | | params.push_back(CParam("ä¸é¡¶Pinå çä½é´è·", "", this->getName().c_str(), v * 0.001f)); |
| | | i += 4; |
| | | |
| | | // 21.è
ä½ç空泵ç空è§è®¾å®å¼ |
| | | params.push_back(CParam("è
ä½ç空泵ç空è§è®¾å®å¼", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | // 21.è
ä½ç空泵ç空è§è®¾å®å¼ |
| | | params.push_back(CParam("è
ä½ç空泵ç空è§è®¾å®å¼", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | i += 4; |
| | | |
| | | // 22.è
ä½ååæ³µå°è¾¾è®¾å®å¼ |
| | | params.push_back(CParam("è
ä½ååæ³µå°è¾¾è®¾å®å¼", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | // 22.è
ä½ååæ³µå°è¾¾è®¾å®å¼ |
| | | params.push_back(CParam("è
ä½ååæ³µå°è¾¾è®¾å®å¼", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | i += 4; |
| | | |
| | | |
| | |
| | | int CBonder::parsingSVData(const char* pszData, size_t size, std::vector<CParam>& params) |
| | | { |
| | | /* |
| | | 1 å·¥èºè¿è¡æ¥éª¤ 1Word 123456 |
| | | 2 æ°åååå½å 2Word 12345.6 |
| | | 3 ä¸è
ååå计 1Word 1234.56 |
| | | 4 管éç空è§å¼ FLOAT 123.456 |
| | | 5 è
ä½ç空è§å¼ FLOAT 123.456 |
| | | 6 ä¸è
温度1 1Word 12345.6 |
| | | 7 ä¸è
温度2 1Word 12345.6 |
| | | 8 ä¸è
温度3 1Word 12345.6 |
| | | 9 ä¸è
温度4 1Word 12345.6 |
| | | 10 ä¸è
温度5 1Word 12345.6 |
| | | 11 ä¸è
温度6 1Word 12345.6 |
| | | 12 ä¸è
温度1 1Word 12345.6 |
| | | 13 ä¸è
温度2 1Word 12345.6 |
| | | 14 ä¸è
温度3 1Word 12345.6 |
| | | 15 ä¸è
温度4 1Word 12345.6 |
| | | 16 ä¸è
温度5 1Word 12345.6 |
| | | 17 ä¸è
温度6 1Word 12345.6 |
| | | 18 ååå©ä½æ¶é´ 1Word 1234.56 |
| | | 1 å·¥èºè¿è¡æ¥éª¤ 1Word 123456 |
| | | 2 æ°åååå½å 2Word 12345.6 |
| | | 3 ä¸è
ååå计 1Word 1234.56 |
| | | 4 管éç空è§å¼ FLOAT 123.456 |
| | | 5 è
ä½ç空è§å¼ FLOAT 123.456 |
| | | 6 ä¸è
温度1 1Word 12345.6 |
| | | 7 ä¸è
温度2 1Word 12345.6 |
| | | 8 ä¸è
温度3 1Word 12345.6 |
| | | 9 ä¸è
温度4 1Word 12345.6 |
| | | 10 ä¸è
温度5 1Word 12345.6 |
| | | 11 ä¸è
温度6 1Word 12345.6 |
| | | 12 ä¸è
温度1 1Word 12345.6 |
| | | 13 ä¸è
温度2 1Word 12345.6 |
| | | 14 ä¸è
温度3 1Word 12345.6 |
| | | 15 ä¸è
温度4 1Word 12345.6 |
| | | 16 ä¸è
温度5 1Word 12345.6 |
| | | 17 ä¸è
温度6 1Word 12345.6 |
| | | 18 ååå©ä½æ¶é´ 1Word 1234.56 |
| | | */ |
| | | |
| | | ASSERT(pszData); |
| | |
| | | int i = 0, v; |
| | | |
| | | |
| | | // 1.å·¥èºè¿è¡æ¥éª¤ |
| | | // 1.å·¥èºè¿è¡æ¥éª¤ |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("å·¥èºè¿è¡æ¥éª¤", "", this->getName().c_str(), v)); |
| | | params.push_back(CParam("å·¥èºè¿è¡æ¥éª¤", "", this->getName().c_str(), v)); |
| | | i += 2; |
| | | |
| | | // 2.æ°åååå½å |
| | | // 2.æ°åååå½å |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8 | (pszData[i + 2] & 0xff) << 16 | (pszData[i + 3] & 0xff) << 24; |
| | | params.push_back(CParam("æ°åååå½å", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("æ°åååå½å", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 4; |
| | | |
| | | // 3.ä¸è
ååå计 |
| | | // 3.ä¸è
ååå计 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
ååå计", "", this->getName().c_str(), ((short)v) * 0.01f)); |
| | | params.push_back(CParam("ä¸è
ååå计", "", this->getName().c_str(), ((short)v) * 0.01f)); |
| | | i += 2; |
| | | |
| | | // 4.管éç空è§å¼ |
| | | params.push_back(CParam("管éç空è§å¼", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | // 4.管éç空è§å¼ |
| | | params.push_back(CParam("管éç空è§å¼", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | i += 4; |
| | | |
| | | // 5.è
ä½ç空è§å¼ |
| | | params.push_back(CParam("è
ä½ç空è§å¼", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | // 5.è
ä½ç空è§å¼ |
| | | params.push_back(CParam("è
ä½ç空è§å¼", "", this->getName().c_str(), (double)toFloat(&pszData[i]))); |
| | | i += 4; |
| | | |
| | | // 6.ä¸è
温度1 |
| | | // 6.ä¸è
温度1 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度1", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度1", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 7.ä¸è
温度2 |
| | | // 7.ä¸è
温度2 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度2", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度2", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 8.ä¸è
温度3 |
| | | // 8.ä¸è
温度3 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度3", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度3", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 9.ä¸è
温度4 |
| | | // 9.ä¸è
温度4 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度4", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度4", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 10.ä¸è
温度5 |
| | | // 10.ä¸è
温度5 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度5", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度5", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 11.ä¸è
温度6 |
| | | // 11.ä¸è
温度6 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度6", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度6", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 12.ä¸è
温度1 |
| | | // 12.ä¸è
温度1 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度1", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度1", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 13.ä¸è
温度2 |
| | | // 13.ä¸è
温度2 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度2", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度2", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 14.ä¸è
温度3 |
| | | // 14.ä¸è
温度3 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度3", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度3", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 15.ä¸è
温度4 |
| | | // 15.ä¸è
温度4 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度4", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度4", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 16.ä¸è
温度5 |
| | | // 16.ä¸è
温度5 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度5", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度5", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 17.ä¸è
温度6 |
| | | // 17.ä¸è
温度6 |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ä¸è
温度6", "", this->getName().c_str(), v * 0.1f)); |
| | | params.push_back(CParam("ä¸è
温度6", "", this->getName().c_str(), v * 0.1f)); |
| | | i += 2; |
| | | |
| | | // 18.å çå©ä½æ¶é´ |
| | | // 18.å çå©ä½æ¶é´ |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("å çå©ä½æ¶é´", "", this->getName().c_str(), v * 0.01f)); |
| | | params.push_back(CParam("å çå©ä½æ¶é´", "", this->getName().c_str(), v * 0.01f)); |
| | | i += 2; |
| | | |
| | | // 19.ååå©ä½æ¶é´ |
| | | // 19.ååå©ä½æ¶é´ |
| | | v = (pszData[i] & 0xff) | (pszData[i + 1] & 0xff) << 8; |
| | | params.push_back(CParam("ååå©ä½æ¶é´", "", this->getName().c_str(), v * 0.01f)); |
| | | params.push_back(CParam("ååå©ä½æ¶é´", "", this->getName().c_str(), v * 0.01f)); |
| | | i += 2; |
| | | |
| | | return (int)params.size(); |
| | |
| | | virtual void getAttributeVector(CAttributeVector& attrubutes); |
| | | virtual int recvIntent(CPin* pPin, CIntent* pIntent); |
| | | virtual int onProcessData(CProcessData* pProcessData); |
| | | virtual int onProcessStateChanged(int slotNo, PROCESS_STATE state); |
| | | virtual int onProcessStateChanged(int slotNo, PROCESS_STATE prevState, PROCESS_STATE state); |
| | | virtual int getIndexerOperationModeBaseValue(); |
| | | virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& parsms); |
| | | virtual int parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& parsms); |
| | |
| | | } |
| | | } |
| | | |
| | | unsigned int CCollectionEvent::getFirstPortID() |
| | | unsigned int CCollectionEvent::getFirstReportID() |
| | | { |
| | | if (m_reports.empty()) return -1; |
| | | if (m_reports.empty()) return 0; |
| | | return m_reports.front()->getReportId(); |
| | | } |
| | | |
| | |
| | | #include "CReport.h" |
| | | #include <vector> |
| | | |
| | | |
| | | namespace SERVO { |
| | | class CCollectionEvent |
| | | { |
| | |
| | | std::string& getDescription(); |
| | | std::vector<CReport*>& getReports(); |
| | | std::string getReportIdsText(); |
| | | const std::vector<unsigned int>& getReportIds() const { return m_rptids; } |
| | | BOOL addReport(CReport* pReport); |
| | | BOOL deleteReport(unsigned int nReportId); |
| | | CReport* getReport(unsigned int nReportId); |
| | | |
| | | /* 妿ä¸ä¸ªCEIDåªæä¸ä¸ªReportçåºæ¯,è°ç¨æ¤å½æ°è®¾ç½®æåæ¶ */ |
| | | void setReport(CReport* pReport); |
| | | unsigned int getFirstPortID(); |
| | | unsigned int getFirstReportID(); |
| | | CReport* getFirstReport(); |
| | | |
| | | private: |
| | |
| | | m_pControlJob->setPJs(pjs); |
| | | m_pControlJob->clearIssues(); |
| | | int nRet = master.setProcessJobs(pjs); |
| | | |
| | | // 没æé®é¢çpjè¦éæ¾ |
| | | for (auto pj : pjs) { |
| | | if (!pj->issues().empty()) { |
| | | delete pj; |
| | | } |
| | | } |
| | | pjs.clear(); |
| | | |
| | | if (nRet <= 0) { |
| | | std::string msg("忥Process Job失败!"); |
| | | for (auto pj : pjs) { |
| | |
| | | msg.append("\n"); |
| | | } |
| | | } |
| | | delete pj; |
| | | } |
| | | pjs.clear(); |
| | | AfxMessageBox(msg.c_str()); |
| | | |
| | | return; |
| | | } |
| | | |
| | | // ç»§ç»éæ¾æé®é¢ç ProcessJob |
| | | for (auto pj : pjs) { |
| | | if (!pj->issues().empty()) { |
| | | delete pj; |
| | | } |
| | | } |
| | | pjs.clear(); |
| | | |
| | | nRet = master.setControlJob(*m_pControlJob); |
| | | if (nRet != 0) { |
| | |
| | | SERVO::CLoadPort* pLoadPort = pPorts[m_pjWarps[p].port]; |
| | | for (int i = 0; i < SLOT_MAX; ++i) { |
| | | SERVO::CSlot* pSlot = pLoadPort->getSlot(i); |
| | | if (!pSlot) { |
| | | continue; |
| | | } |
| | | if (!pSlot) continue; |
| | | |
| | | SERVO::CGlass* pGlass = dynamic_cast<SERVO::CGlass*>(pSlot->getContext()); |
| | | if (pGlass == nullptr) continue; |
| | | |
| | | SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS(); |
| | | if (pJobDataS == nullptr) continue; |
| | | |
| | | |
| | | // 设置 Panel ID åå¾éæ¡ |
| | | SERVO::CProcessJob* pj = (SERVO::CProcessJob*)m_pjWarps[p].pj; |
| | | int nRecipeID = RecipeManager::getInstance().getIdByPPID(pj->recipeSpec()); |
| | | RecipeInfo stRecipeInfo = RecipeManager::getInstance().getRecipeByPPID(pj->recipeSpec()); |
| | | std::vector<DeviceRecipe> vecRecipeInfo = stRecipeInfo.vecDeviceList; |
| | | SERVO::CGlass* pGlass = dynamic_cast<SERVO::CGlass*>(pSlot->getContext()); |
| | | SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS(); |
| | | if (pGlass != nullptr && pJobDataS != nullptr) { |
| | | |
| | | pGlass->setScheduledForProcessing(m_pjWarps[p].checkSlot[i]); |
| | | pGlass->setType(static_cast<SERVO::MaterialsType>(m_pjWarps[p].material[i])); |
| | | |
| | | SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS(); |
| | | pJobDataS->setLotId(pj->getLotId().c_str()); |
| | | pJobDataS->setProductId(pj->getProductId().c_str()); |
| | | pJobDataS->setOperationId(pj->getOperationId().c_str()); |
| | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // process start |
| | | for (int p = 0; p < 4; p++) { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | |
| | | #include "CVariable.h" |
| | | |
| | | namespace SERVO { |
| | | // Data Variable:è¯ä¹å CVariableï¼ä½ç¨äº DVIDï¼æ°æ®åéï¼éåã |
| | | class CDataVariable : public CVariable |
| | | { |
| | | public: |
| | | using CVariable::CVariable; // å¤ç¨åºç±»æé |
| | | ~CDataVariable() = default; |
| | | }; |
| | | } |
| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "CEquipment.h" |
| | | #include "ToolUnits.h" |
| | | #include <regex> |
| | |
| | | void CEquipment::getProperties(std::vector<std::pair<std::string, std::string>>& container) |
| | | { |
| | | container.clear(); |
| | | // 示ä¾ï¼å°ä¸äºå±æ§æ·»å å°å®¹å¨ |
| | | // 示ä¾ï¼å°ä¸äºå±æ§æ·»å å°å®¹å¨ |
| | | container.push_back(std::make_pair("DeviceName", "ServoMotor")); |
| | | container.push_back(std::make_pair("SerialNumber", "123456789")); |
| | | container.push_back(std::make_pair("Version", "1.0")); |
| | |
| | | { |
| | | if (nSlotNo <= 0 || nSlotNo > 8) return; |
| | | |
| | | const auto prevState = m_processState[nSlotNo - 1]; |
| | | m_processState[nSlotNo - 1] = state; |
| | | onProcessStateChanged(nSlotNo, m_processState[nSlotNo - 1]); |
| | | onProcessStateChanged(nSlotNo, prevState, m_processState[nSlotNo - 1]); |
| | | |
| | | if (m_listener.onProcessStateChanged != nullptr) { |
| | | m_listener.onProcessStateChanged(this, nSlotNo, m_processState[nSlotNo - 1]); |
| | | m_listener.onProcessStateChanged(this, nSlotNo, prevState, m_processState[nSlotNo - 1]); |
| | | } |
| | | } |
| | | |
| | |
| | | std::string& CEquipment::getDescription() |
| | | { |
| | | return m_strDescription; |
| | | } |
| | | |
| | | void CEquipment::setCurrentRecipe(const std::string& recipe) |
| | | { |
| | | Lock(); |
| | | m_currentRecipe = recipe; |
| | | Unlock(); |
| | | } |
| | | |
| | | std::string CEquipment::getCurrentRecipe() |
| | | { |
| | | Lock(); |
| | | std::string out = m_currentRecipe; |
| | | Unlock(); |
| | | return out; |
| | | } |
| | | |
| | | void CEquipment::setStation(int network, int station) |
| | |
| | | |
| | | void CEquipment::onTimer(UINT nTimerid) |
| | | { |
| | | // æ¯éä¸ç§ï¼æ£æ¥ä¸ä¸ALIVEç¶æ |
| | | // æ¯éä¸ç§ï¼æ£æ¥ä¸ä¸ALIVEç¶æ |
| | | |
| | | static int tick = 0; |
| | | tick++; |
| | |
| | | } |
| | | } |
| | | |
| | | // 梳çåç»çä¹é´çç»å®å
³ç³» |
| | | // 梳çåç»çä¹é´çç»å®å
³ç³» |
| | | /* |
| | | Lock(); |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | |
| | | CGlass* pBudy = (CGlass*)m_slot[j].getContext(); |
| | | if (pBudy != nullptr && strBuddyId.compare(pBudy->getID()) == 0) { |
| | | pGlass->setBuddy(pBudy); |
| | | TRACE("ç»å®å
³ç³»: %s <- %s\n", pGlass->getID().c_str(), pBudy->getID().c_str()); |
| | | TRACE("ç»å®å
³ç³»: %s <- %s\n", pGlass->getID().c_str(), pBudy->getID().c_str()); |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | */ |
| | | |
| | | // è¿æ¥ä¿¡å·è§£éåä¿å |
| | | // è¿æ¥ä¿¡å·è§£éåä¿å |
| | | BOOL bFlag; |
| | | int index = 0; |
| | | for (int i = 0; i < 8; i++) { |
| | |
| | | } |
| | | |
| | | |
| | | // å
¶å®ä¿¡å·åååº |
| | | // å
¶å®ä¿¡å·åååº |
| | | index = 0x540; |
| | | |
| | | |
| | |
| | | m_alive.flag = bFlag; |
| | | m_alive.count = 0; |
| | | |
| | | // ״̬ |
| | | // ç¶æ |
| | | if (!m_alive.alive) { |
| | | m_alive.alive = TRUE; |
| | | if (m_listener.onAlive != nullptr) { |
| | |
| | | } |
| | | |
| | | |
| | | // 以䏿 ¹æ®ä¿¡å·åæµç¨å¤ç |
| | | // 以䏿 ¹æ®ä¿¡å·åæµç¨å¤ç |
| | | for (int i = 0; i < 7; i++) { |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_EQMODE_CHANGED + i, pszData, size); |
| | | } |
| | |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_PROCESS_DATA_REPORT, pszData, size); |
| | | |
| | | // FAC Data report |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_FAC_DATA_REPORT, pszData, size); |
| | | // CHECK_READ_STEP_SIGNAL(STEP_ID_FAC_DATA_REPORT, pszData, size); |
| | | { |
| | | SERVO::CStep* pStep = getStep(STEP_ID_FAC_DATA_REPORT); |
| | | if (pStep != nullptr) { |
| | | ((CReadStep*)pStep)->onReadSignal(TRUE); |
| | | } |
| | | } |
| | | |
| | | // é
æ¹æ¹å |
| | | |
| | | // é
æ¹æ¹å |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_CURRENT_RECIPE_CHANGE_REPORT, pszData, size); |
| | | |
| | | // 主é
æ¹ä¸æ¥ |
| | | // 主é
æ¹ä¸æ¥ |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_MASTER_RECIPE_LIST_REPORT, pszData, size); |
| | | |
| | | // é
æ¹åæ° |
| | | // é
æ¹åæ° |
| | | CHECK_WRITE_STEP_SIGNAL(STEP_ID_RECIPE_PARAMETER_CMD_REPLY, pszData, size); |
| | | CHECK_READ_STEP_SIGNAL(STEP_ID_RECIPE_PARAMETER_REPORT, pszData, size); |
| | | |
| | |
| | | else if (isCimMessageConfirmStep(pStep)) { |
| | | SERVO::CEqReadIntStep* pEqReadIntStep = (SERVO::CEqReadIntStep*)pStep; |
| | | int value = pEqReadIntStep->getValue(); |
| | | // æ¤å¤å°valueæé«ä½ä½æå为message idåpanel no. |
| | | // å¯è½è¿éè¦ä¸æ¥å°cim |
| | | // æ¤å¤å°valueæé«ä½ä½æå为message idåpanel no. |
| | | // å¯è½è¿éè¦ä¸æ¥å°cim |
| | | short msgId, panelNo; |
| | | msgId = (value & 0xffff0000 >> 16); |
| | | panelNo = (value & 0xffff); |
| | |
| | | m_listener.onVcrEventReport(this, pVcrEventReport); |
| | | } |
| | | |
| | | // 0426, å
åºå®è¿å1(OK) |
| | | // 0426, å
åºå®è¿å1(OK) |
| | | pEqVcrEventStep->setReturnCode(1); |
| | | return 1; |
| | | } |
| | |
| | | |
| | | CPin* CEquipment::addPin(PinType type, char* pszName) |
| | | { |
| | | // ä¸å
许ååæ·»å éå¤çpin |
| | | // ä¸å
许ååæ·»å éå¤çpin |
| | | CPin* pPin = getPin(pszName); |
| | | if (pPin != nullptr) return nullptr; |
| | | |
| | | |
| | | // æ·»å å°Pinå表ï¼çæ¯è¾å
¥pinæè¾åºpin |
| | | // æ·»å å°Pinå表ï¼çæ¯è¾å
¥pinæè¾åºpin |
| | | if (type == PinType::INPUT) { |
| | | pPin = new CPin(this, type, pszName); |
| | | m_inputPins.push_back(pPin); |
| | |
| | | CEquipment* pFromEq = pFromPin->getEquipment(); |
| | | ASSERT(pFromEq); |
| | | |
| | | LOGD("<CEquipment><%s-%s>æ¶å°æ¥èª<%s.%s>çIntent<%d,%s,0x%x>", |
| | | LOGD("<CEquipment><%s-%s>æ¶å°æ¥èª<%s.%s>çIntent<%d,%s,0x%x>", |
| | | this->getName().c_str(), |
| | | pPin->getName().c_str(), |
| | | pFromEq->getName().c_str(), |
| | |
| | | |
| | | |
| | | |
| | | // 以ä¸è§£éå¤çæ°æ® |
| | | // 以ä¸è§£éå¤çæ°æ® |
| | | int code = pIntent->getCode(); |
| | | |
| | | |
| | | // æµè¯ |
| | | // æµè¯ |
| | | if (code == FLOW_TEST) { |
| | | AfxMessageBox(pIntent->getMsg()); |
| | | } |
| | |
| | | return -1; |
| | | } |
| | | |
| | | // æ¾å°æå®çglass id, |
| | | // æ¾å°æå®çglass id, |
| | | Lock(); |
| | | CGlass* pContext = nullptr; |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | |
| | | CGlass* pBuddy = pGlass->getBuddy(); |
| | | if (pBuddy != nullptr) pBuddy->addPath(m_nID, getSlotUnit(putSlot), putSlot); |
| | | m_slot[putSlot - 1].setContext(pGlass); |
| | | pGlass->release(); // tempFetchOutéè¦è°ç¨ä¸æ¬¡release |
| | | pGlass->release(); // tempFetchOutéè¦è°ç¨ä¸æ¬¡release |
| | | Unlock(); |
| | | |
| | | /* |
| | |
| | | return -1; |
| | | } |
| | | |
| | | LOGI("<CEquipment-%s>åå¤è®¾ç½®DispatchingMode<%d>", m_strName.c_str(), (int)mode); |
| | | LOGI("<CEquipment-%s>åå¤è®¾ç½®DispatchingMode<%d>", m_strName.c_str(), (int)mode); |
| | | if (onWritedBlock != nullptr) { |
| | | pStep->writeShort((short)mode, onWritedBlock); |
| | | } |
| | | else { |
| | | pStep->writeShort((short)mode, [&, mode](int code) -> int { |
| | | if (code == WOK) { |
| | | LOGI("<CEquipment-%s>设置DispatchingModeæå.", m_strName.c_str()); |
| | | LOGI("<CEquipment-%s>设置DispatchingModeæå.", m_strName.c_str()); |
| | | } |
| | | else { |
| | | LOGE("<CEquipment-%s>设置DispatchingMode失败ï¼code:%d", m_strName.c_str(), code); |
| | | LOGE("<CEquipment-%s>设置DispatchingMode失败ï¼code:%d", m_strName.c_str(), code); |
| | | } |
| | | |
| | | return 0; |
| | |
| | | } |
| | | |
| | | unsigned short operationMode = (unsigned short)((unsigned short)mode + getIndexerOperationModeBaseValue()); |
| | | LOGI("<CEquipment-%s>åå¤è®¾ç½®indexerOperationMode<%d>", m_strName.c_str(), (int)mode); |
| | | LOGI("<CEquipment-%s>åå¤è®¾ç½®indexerOperationMode<%d>", m_strName.c_str(), (int)mode); |
| | | pStep->writeShort(operationMode, [&, pStep, mode, onWritedRetBlock](int code) -> int { |
| | | int retCode = 0; |
| | | if (code == WOK) { |
| | | LOGI("<CEquipment-%s>设置indexerOperationModeæå.", m_strName.c_str()); |
| | | LOGI("<CEquipment-%s>设置indexerOperationModeæå.", m_strName.c_str()); |
| | | const char* pszRetData = nullptr; |
| | | pStep->getReturnData(pszRetData); |
| | | ASSERT(pszRetData); |
| | | retCode = (unsigned int)CToolUnits::toInt16(pszRetData); |
| | | LOGI("<CEquipment-%s>è¿åå¼: %d", m_strName.c_str(), retCode); |
| | | LOGI("<CEquipment-%s>è¿åå¼: %d", m_strName.c_str(), retCode); |
| | | } |
| | | else { |
| | | LOGE("<CEquipment-%s>设置indexerOperationMode失败ï¼code:%d", m_strName.c_str(), code); |
| | | LOGE("<CEquipment-%s>设置indexerOperationMode失败ï¼code:%d", m_strName.c_str(), code); |
| | | } |
| | | |
| | | if (onWritedRetBlock != nullptr) { |
| | |
| | | return -1; |
| | | } |
| | | |
| | | LOGI("<CEquipment-%s>æ£å¨è¯·æ±åå
<%d>主é
æ¹å表", m_strName.c_str(), unitNo); |
| | | LOGI("<CEquipment-%s>æ£å¨è¯·æ±åå
<%d>主é
æ¹å表", m_strName.c_str(), unitNo); |
| | | m_recipesManager.setOnSyncingStateChanged(block); |
| | | if (m_recipesManager.syncing() != 0) { |
| | | return -2; |
| | | } |
| | | pStep->writeShort(unitNo, [&, unitNo](int code) -> int { |
| | | if (code == WOK) { |
| | | LOGI("<CEquipment-%s>请æ±åå
<%d>主é
æ¹å表æåï¼æ£å¨çå¾
æ°æ®.", m_strName.c_str(), unitNo); |
| | | LOGI("<CEquipment-%s>请æ±åå
<%d>主é
æ¹å表æåï¼æ£å¨çå¾
æ°æ®.", m_strName.c_str(), unitNo); |
| | | } |
| | | else { |
| | | m_recipesManager.syncFailed(); |
| | | LOGE("<CEquipment-%s>请æ±åå
<%d>主é
æ¹å表失败ï¼code:%d", m_strName.c_str(), unitNo, code); |
| | | LOGE("<CEquipment-%s>请æ±åå
<%d>主é
æ¹å表失败ï¼code:%d", m_strName.c_str(), unitNo, code); |
| | | } |
| | | |
| | | return 0; |
| | |
| | | |
| | | int CEquipment::recipeParameterRequest(short masterRecipeId, short localRecipeId, short unitNo, ONSYNCINGSTATECHANGED block) |
| | | { |
| | | LOGI("<CEquipment-%s>æ£å¨è¯·æ±åå
<%d>主é
åæ°å表", m_strName.c_str(), unitNo); |
| | | LOGI("<CEquipment-%s>æ£å¨è¯·æ±åå
<%d>主é
åæ°å表", m_strName.c_str(), unitNo); |
| | | m_recipesManager.setOnSyncingStateChanged(block); |
| | | if (m_recipesManager.syncing() != 0) { |
| | | return -2; |
| | |
| | | |
| | | pStep->writeDataEx(szBuffer, 14 * 2, [&, unitNo](int code) -> int { |
| | | if (code == WOK) { |
| | | LOGI("<CEquipment-%s>请æ±åå
<%d>主é
æ¹åæ°å表æåï¼æ£å¨çå¾
æ°æ®.", m_strName.c_str(), unitNo); |
| | | LOGI("<CEquipment-%s>请æ±åå
<%d>主é
æ¹åæ°å表æåï¼æ£å¨çå¾
æ°æ®.", m_strName.c_str(), unitNo); |
| | | } |
| | | else { |
| | | m_recipesManager.syncFailed(); |
| | | LOGE("<CEquipment-%s>请æ±åå
<%d>主é
æ¹åæ°å表失败ï¼code:%d", m_strName.c_str(), unitNo, code); |
| | | LOGE("<CEquipment-%s>请æ±åå
<%d>主é
æ¹åæ°å表失败ï¼code:%d", m_strName.c_str(), unitNo, code); |
| | | } |
| | | |
| | | return 0; |
| | |
| | | int nRet = processData.unserialize(&pszData[0], (int)size); |
| | | if (nRet < 0) return nRet; |
| | | |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | unsigned int weight = 201; |
| | | CAttributeVector& attrubutes = pStep->attributeVector(); |
| | | processData.getAttributeVector(attrubutes, weight); |
| | |
| | | |
| | | |
| | | |
| | | // æ¾å°ç»çï¼å
³èæ°æ® |
| | | // æ¾å°ç»çï¼å
³èæ°æ® |
| | | CGlass* pGlass = this->getGlassWithCassette(processData.getCassetteSequenceNo(), |
| | | processData.getJobSequenceNo()); |
| | | if (pGlass == nullptr) { |
| | | LOGE("<CEquipment-%s>æ¾ä¸å°å¯¹åºGlass, å
³èå·¥èºåæ°å¤±è´¥ãCassetteSequenceNo:%d/%d", |
| | | LOGE("<CEquipment-%s>æ¾ä¸å°å¯¹åºGlass, å
³èå·¥èºåæ°å¤±è´¥ãCassetteSequenceNo:%d/%d", |
| | | this->getName().c_str(), |
| | | processData.getCassetteSequenceNo(), |
| | | processData.getJobSequenceNo()); |
| | |
| | | std::vector<CParam> tempParams; |
| | | this->parsingProcessData((const char*)rawData.data(), rawData.size(), tempParams); |
| | | int n = processData.getTotalParameter(); |
| | | std::vector<CParam> params(tempParams.begin(), tempParams.begin() + min(n, (int)tempParams.size())); |
| | | std::vector<CParam> params(tempParams.begin(), tempParams.begin() + (std::min)(n, (int)tempParams.size())); |
| | | pGlass->addParams(params); |
| | | if (m_listener.onProcessDataReport != nullptr) { |
| | | m_listener.onProcessDataReport(this, params); |
| | | } |
| | | |
| | | // å
³èçGlassä¹è¦æ´æ° |
| | | // å
³èçGlassä¹è¦æ´æ° |
| | | CGlass* pBuddy = pGlass->getBuddy(); |
| | | LOGI("<Equipment-%s>decodeProcessDataReport pBuddy=%x %s", getName().c_str(), pBuddy, pGlass->getID().c_str()); |
| | | if (pBuddy != nullptr) { |
| | | LOGI("<Equipment-%s>decodeProcessDataReport addParams pBuddy=%x %s", getName().c_str(), pBuddy, pGlass->getID().c_str()); |
| | | pBuddy->addParams(params); |
| | | if (m_listener.onProcessDataReport != nullptr) { |
| | | m_listener.onProcessDataReport(this, params); |
| | | } |
| | | } |
| | | |
| | | return nRet; |
| | |
| | | int nRet = jobDataS.unserialize(&pszData[0], (int)size); |
| | | if (nRet < 0) return nRet; |
| | | |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | unsigned int weight = 201; |
| | | CAttributeVector& attrubutes = pStep->attributeVector(); |
| | | jobDataS.getAttributeVector(attrubutes, weight); |
| | |
| | | LOGI("<CEquipment-%s>onReceivedJob.", m_strName.c_str()); |
| | | |
| | | |
| | | // å¯ä»¥å¨æ¤æ´æ°JobDataSæ°æ®äº |
| | | // å¯ä»¥å¨æ¤æ´æ°JobDataSæ°æ®äº |
| | | int nRet = ((CArm*)m_pArm)->glassUpdateJobDataS(pJobDataS); |
| | | if (nRet < 0) { |
| | | LOGE("<CEquipment-%s>onReceivedJob,æ´æ°JobDataS失败ï¼glassUpdateJobDataSè¿å%d", |
| | | LOGE("<CEquipment-%s>onReceivedJob,æ´æ°JobDataS失败ï¼glassUpdateJobDataSè¿å%d", |
| | | m_strName.c_str(), nRet); |
| | | } |
| | | |
| | | if (m_listener.onReceivedJob != nullptr) { |
| | | m_listener.onReceivedJob(this, port, pJobDataS); |
| | | } |
| | | |
| | | return nRet; |
| | |
| | | int nRet = jobDataS.unserialize(&pszData[0], (int)size); |
| | | if (nRet < 0) return nRet; |
| | | |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | unsigned int weight = 201; |
| | | CAttributeVector& attrubutes = pStep->attributeVector(); |
| | | jobDataS.getAttributeVector(attrubutes, weight); |
| | |
| | | int CEquipment::onSentOutJob(int port, CJobDataS* pJobDataS) |
| | | { |
| | | LOGI("<CEquipment-%s>onSentOutJob.", m_strName.c_str()); |
| | | |
| | | if (m_listener.onSentOutJob != nullptr) { |
| | | m_listener.onSentOutJob(this, port, pJobDataS); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | |
| | | index += sizeof(short); |
| | | |
| | | |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | unsigned int weight = 201; |
| | | pStep->addAttribute(new CAttribute("UnitOrPort", |
| | | std::to_string(unitOrPort).c_str(), "", weight++)); |
| | |
| | | return fetchedOutJob(port, pJobDataB); |
| | | } |
| | | |
| | | // æ°æ®å¼å¸¸ï¼å¤çææ¾ç¤º |
| | | // æ°æ®å¼å¸¸ï¼å¤çææ¾ç¤º |
| | | LOGI("<CEquipment-%s>onFetchedOutJob Error.ort:%d|GlassId:%s", |
| | | m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); |
| | | return -1; |
| | |
| | | index += sizeof(short); |
| | | |
| | | |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | unsigned int weight = 201; |
| | | pStep->addAttribute(new CAttribute("UnitOrPort", |
| | | std::to_string(unitOrPort).c_str(), "", weight++)); |
| | |
| | | vcrEventReport.getGlassId().c_str()); |
| | | |
| | | |
| | | // æ´æ°GlassçID |
| | | // æ´æ°GlassçID |
| | | CGlass* pGlass = getGlassWithCassette(vcrEventReport.getCassetteSequenceNo(), |
| | | vcrEventReport.getJobSequenceNo()); |
| | | if (pGlass != nullptr) { |
| | |
| | | } |
| | | |
| | | |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | unsigned int weight = 201; |
| | | CAttributeVector& attrubutes = pStep->attributeVector(); |
| | | vcrEventReport.getAttributeVector(attrubutes, weight); |
| | | |
| | | |
| | | // 0426, å
åºå®è¿å1(OK) |
| | | // 0426, å
åºå®è¿å1(OK) |
| | | ((CReadStep*)pStep)->setReturnCode((short)VCR_Reply_Code::OK); |
| | | |
| | | |
| | |
| | | index += 256 * 2; |
| | | |
| | | |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | unsigned int weight = 201; |
| | | pStep->addAttribute(new CAttribute("CassetteNo", |
| | | std::to_string(cassetteNo).c_str(), "", weight++)); |
| | |
| | | strPanelGradeData.c_str(), "", weight++)); |
| | | |
| | | |
| | | // æ´æ°æ£æµç»æ |
| | | // æ´æ°æ£æµç»æ |
| | | CGlass* pGlass = getGlassWithCassette(cassetteNo, jobSequenceNo); |
| | | if (pGlass == nullptr) { |
| | | LOGE("<CEquipment-%s>æ´æ°Panel Dataå¤±è´¥ï¼æ¾ä¸å°å¯¹åºçGlass.cassetteNo=%d, jobSequenceNo=%d", |
| | | LOGE("<CEquipment-%s>æ´æ°Panel Dataå¤±è´¥ï¼æ¾ä¸å°å¯¹åºçGlass.cassetteNo=%d, jobSequenceNo=%d", |
| | | getName().c_str(), cassetteNo, jobSequenceNo); |
| | | return -1; |
| | | } |
| | |
| | | CSVData svData; |
| | | int nRet = svData.unserialize(&pszData[0], (int)size); |
| | | if (nRet < 0) return nRet; |
| | | Lock(); |
| | | m_svDatas.push_back(svData); |
| | | Unlock(); |
| | | |
| | | if (m_listener.onSVDataReport != nullptr) { |
| | | m_listener.onSVDataReport(this, &svData); |
| | |
| | | |
| | | |
| | | |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | unsigned int weight = 201; |
| | | pStep->addAttribute(new CAttribute("CassetteSequenceNo", |
| | | (std::to_string(cassetteSequenceNo)).c_str(), "", weight++)); |
| | |
| | | |
| | | CGlass* pGlass = getGlassFromSlot(slotNo); |
| | | if (pGlass == nullptr) { |
| | | LOGE("<CEquipment-%s>decodeJobProcessStartReport, æ¾ä¸å°å¯¹åºglass", getName().c_str()); |
| | | LOGE("<CEquipment-%s>decodeJobProcessStartReport, æ¾ä¸å°å¯¹åºglass", getName().c_str()); |
| | | } |
| | | if (slotNo <= 0 || slotNo > 8) return -1; |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | unsigned int weight = 201; |
| | | pStep->addAttribute(new CAttribute("CassetteNo", |
| | | std::to_string(cassetteNo).c_str(), "", weight++)); |
| | |
| | | } |
| | | |
| | | if (pGlass == nullptr) { |
| | | LOGE("<CEquipment-%s>decodeJobProcessEndReport, æ¾ä¸å°å¯¹åºglass", getName().c_str()); |
| | | LOGE("<CEquipment-%s>decodeJobProcessEndReport, æ¾ä¸å°å¯¹åºglass", getName().c_str()); |
| | | } |
| | | else { |
| | | CJobDataS* pJs = pGlass->getJobDataS(); |
| | |
| | | pGlass->processEnd(m_nID, getSlotUnit(slotNo)); |
| | | } |
| | | else { |
| | | LOGE("<CEquipment-%s>decodeJobProcessEndReport, jobSequenceNoæjobSequenceNoä¸å¹é
", |
| | | LOGE("<CEquipment-%s>decodeJobProcessEndReport, jobSequenceNoæjobSequenceNoä¸å¹é
", |
| | | getName().c_str()); |
| | | } |
| | | } |
| | |
| | | |
| | | |
| | | |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | // ç¼åAttributeï¼ç¨äºè°è¯æ¶æ¾ç¤ºä¿¡æ¯ |
| | | unsigned int weight = 201; |
| | | pStep->addAttribute(new CAttribute("CassetteNo", |
| | | std::to_string(cassetteNo).c_str(), "", weight++)); |
| | |
| | | LOGI("<CEquipment-%s>onPreStoredJob:port:%d|GlassId:%s", |
| | | m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); |
| | | |
| | | // å½åè¦åçï¼ä¹åè¯å®ææçï¼å æ¤çåå¨Armé£é |
| | | // å½åè¦åçï¼ä¹åè¯å®ææçï¼å æ¤çåå¨Armé£é |
| | | CGlass* pGlass = ((CArm*)m_pArm)->getGlassFromSlot(1); |
| | | if (pGlass == nullptr) { |
| | | LOGE("<CFliper-%s>onPreStoredJob,ç¼å䏿²¡ææ¾å°å¯¹åºçGlass(CassetteSequenceNo:%d, JobSequenceNo:%d)ï¼è¯·æ£æ¥æ°æ®ï¼æ³¨æé£é©ã", m_strName.c_str(), |
| | | LOGE("<CFliper-%s>onPreStoredJob,ç¼å䏿²¡ææ¾å°å¯¹åºçGlass(CassetteSequenceNo:%d, JobSequenceNo:%d)ï¼è¯·æ£æ¥æ°æ®ï¼æ³¨æé£é©ã", m_strName.c_str(), |
| | | pJobDataB->getCassetteSequenceNo(), pJobDataB->getJobSequenceNo()); |
| | | return FALSE; |
| | | } |
| | |
| | | CJobDataS* pJobDataS = pGlass->getJobDataS(); |
| | | ASSERT(pJobDataS); |
| | | if (!compareJobData(pJobDataB, pJobDataS)) { |
| | | LOGE("<CEquipemnt-%s>onPreStoredJob,JobDataæ°æ®ä¸å¹é
(JobDataB(%d, %d),JobDataS(%d, %d)), æ³¨æææ¥é£é©!", m_strName.c_str(), |
| | | LOGE("<CEquipemnt-%s>onPreStoredJob,JobDataæ°æ®ä¸å¹é
(JobDataB(%d, %d),JobDataS(%d, %d)), æ³¨æææ¥é£é©!", m_strName.c_str(), |
| | | pJobDataB->getCassetteSequenceNo(), pJobDataB->getJobSequenceNo(), |
| | | pJobDataS->getCassetteSequenceNo(), pJobDataS->getJobSequenceNo()); |
| | | return FALSE; |
| | | } |
| | | |
| | | // å¦ææ²¡æå¯ç¨ä½ç½®ï¼æ¥é |
| | | // å¦ææ²¡æå¯ç¨ä½ç½®ï¼æ¥é |
| | | Lock(); |
| | | CSlot* pSlot = getSlot(putSlot - 1); |
| | | ASSERT(pSlot); |
| | | if (pSlot->getContext() != nullptr) { |
| | | Unlock(); |
| | | LOGE("<CEquipemnt-%s>onPreStoredJob,æå®slot(port:%d)ææï¼è¯·æ³¨æé£é©ï¼", m_strName.c_str(), port); |
| | | LOGE("<CEquipemnt-%s>onPreStoredJob,æå®slot(port:%d)ææï¼è¯·æ³¨æé£é©ï¼", m_strName.c_str(), port); |
| | | return FALSE; |
| | | } |
| | | Unlock(); |
| | |
| | | return storedJob(port, pJobDataB, putSlot); |
| | | } |
| | | |
| | | // æ°æ®å¼å¸¸ï¼å¤çææ¾ç¤º |
| | | // æ°æ®å¼å¸¸ï¼å¤çææ¾ç¤º |
| | | LOGI("<CEquipment-%s>onStoredJob Error.port:%d|GlassId:%s", |
| | | m_strName.c_str(), port, pJobDataB->getGlassId().c_str()); |
| | | return -1; |
| | |
| | | } |
| | | |
| | | /* |
| | | * å½ä»CC-Linkæ£æµå°è®¾å¤Send Able为Onæ¶è°ç¨æ¤å½æ° |
| | | * å¯è½ä¼å¤æ¬¡éå¤è°ç¨(æ ¹æ®æ«æé¢ç), 注æé²å |
| | | * å½ä»CC-Linkæ£æµå°è®¾å¤Send Able为Onæ¶è°ç¨æ¤å½æ° |
| | | * å¯è½ä¼å¤æ¬¡éå¤è°ç¨(æ ¹æ®æ«æé¢ç), 注æé²å |
| | | */ |
| | | int CEquipment::onSendAble(int port) |
| | | { |
| | |
| | | return 0; |
| | | } |
| | | |
| | | int CEquipment::onProcessStateChanged(int nSlotNo, PROCESS_STATE state) |
| | | int CEquipment::onProcessStateChanged(int nSlotNo, PROCESS_STATE prevState, PROCESS_STATE state) |
| | | { |
| | | return 0; |
| | | } |
| | |
| | | }); |
| | | pStep->setName(STEP_EQ_FAC_DATA_REPORT); |
| | | pStep->setProp("Port", (void*)(__int64)port); |
| | | pStep->setReadContinue(TRUE); |
| | | pStep->setWriteSignalDev(writeSignalDev); |
| | | if (addStep(STEP_ID_FAC_DATA_REPORT, pStep) != 0) { |
| | | delete pStep; |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include "Log.h" |
| | | #include "ServoCommo.h" |
| | | #include "CCLinkIEControl.h" |
| | |
| | | typedef std::function<void(void* pEiuipment, void* pReport)> ONVCREVENTREPORT; |
| | | typedef std::function<BOOL(void* pEiuipment, int port, CJobDataB* pJobDataB)> ONPREFETCHEDOUTJOB; |
| | | typedef std::function<BOOL(void* pEiuipment, int port, CJobDataB* pJobDataB, short& putSlot)> ONPRESTOREDJOB; |
| | | typedef std::function<void(void* pEiuipment, int nSlotNo, PROCESS_STATE state)> ONPROCESSSTATE; |
| | | typedef std::function<void(void* pEiuipment, int nSlotNo, PROCESS_STATE prevState, PROCESS_STATE state)> ONPROCESSSTATE; |
| | | typedef std::function<void(void* pEiuipment, short scanMap, short downMap)> ONMAPMISMATCH; |
| | | typedef std::function<void(void* pEiuipment, short status, __int64 data)> ONPORTSTATUSCHANGED; |
| | | typedef std::function<void(void* pEiuipment, const std::vector<CParam>& params)> ONPROCESSDATAREPORT; |
| | | typedef std::function<void(void* pEiuipment, int port, CJobDataS* pJobDataS)> ONRECEIVEDJOB; |
| | | typedef std::function<void(void* pEiuipment, int port, CJobDataS* pJobDataS)> ONSENTOUTJOB; |
| | | |
| | | typedef struct _EquipmentListener |
| | | { |
| | |
| | | ONPORTSTATUSCHANGED onPortStatusChanged; |
| | | ONVCREVENTREPORT onSVDataReport; |
| | | ONVCREVENTREPORT onPanelDataReport; |
| | | ONPROCESSDATAREPORT onProcessDataReport; |
| | | ONRECEIVEDJOB onReceivedJob; |
| | | ONSENTOUTJOB onSentOutJob; |
| | | } EquipmentListener; |
| | | |
| | | |
| | |
| | | std::string& getName(); |
| | | void setDescription(const char* pszDescription); |
| | | std::string& getDescription(); |
| | | void setCurrentRecipe(const std::string& recipe); |
| | | std::string getCurrentRecipe(); |
| | | void setStation(int network, int station); |
| | | const StationIdentifier& getStation(); |
| | | virtual void getAttributeVector(CAttributeVector& attrubutes); |
| | |
| | | virtual int onProcessData(CProcessData* pProcessData); |
| | | virtual int onSendAble(int port); |
| | | virtual int onReceiveAble(int port); |
| | | virtual int onProcessStateChanged(int nSlotNo, PROCESS_STATE state); |
| | | virtual int onProcessStateChanged(int nSlotNo, PROCESS_STATE prevState, PROCESS_STATE state); |
| | | virtual int getIndexerOperationModeBaseValue(); |
| | | virtual bool isSlotProcessed(int slot) { return true; }; |
| | | bool isAlarmStep(SERVO::CStep* pStep); |
| | |
| | | void printDebugString001(); |
| | | std::vector<SERVO::CSVData>& getSVDatas(); |
| | | |
| | | // 请æ±ä¸»é
æ¹å表 |
| | | // 请æ±ä¸»é
æ¹å表 |
| | | // unitNo: 0:local; Others:unit No |
| | | int masterRecipeListRequest(short unitNo, ONSYNCINGSTATECHANGED block); |
| | | |
| | | // 请æ±é
æ¹åæ° |
| | | // masterRecipeId: 主é
æ¹id |
| | | // localRecipeId: æ¬å°é
æ¹id |
| | | // 请æ±é
æ¹åæ° |
| | | // masterRecipeId: 主é
æ¹id |
| | | // localRecipeId: æ¬å°é
æ¹id |
| | | // unitNo: 0:local; Others:unit No |
| | | int recipeParameterRequest(short masterRecipeId, short localRecipeId, short unitNo, ONSYNCINGSTATECHANGED block); |
| | | |
| | | // è§£æé
æ¹åæ°å表 |
| | | // è§£æé
æ¹åæ°å表 |
| | | virtual int parsingParams(const char* pszData, size_t size, std::vector<CParam>& params) { return 0; }; |
| | | virtual int parsingParams(const char* pszData, size_t size, std::string& strOut); |
| | | virtual int parsingProcessData(const char* pszData, size_t size, std::vector<CParam>& params) { return 0; }; |
| | | virtual int parsingSVData(const char* pszData, size_t size, std::vector<CParam>& params) { return 0; }; |
| | | |
| | | // è·åæå®çSlot |
| | | // è·åæå®çSlot |
| | | CSlot* getSlot(int index); |
| | | CSlot* getSlotWithNo(int slotNo); |
| | | |
| | | // è·åä¸ä¸ªå¯ç¨çæ§½ä½ |
| | | // è·åä¸ä¸ªå¯ç¨çæ§½ä½ |
| | | CSlot* getAvailableSlot(); |
| | | |
| | | // è·åä¸ä¸ªæå®ç©æç±»å(G1,G2,G1&G2)çç©ºæ§½ä½ |
| | | // è·åä¸ä¸ªæå®ç©æç±»å(G1,G2,G1&G2)çç©ºæ§½ä½ |
| | | CSlot* getAvailableSlotForGlass(MaterialsType type); |
| | | CSlot* getAvailableSlotForGlassExcludeSignal(MaterialsType type); |
| | | CSlot* isSlotAvailable(unsigned int slot); |
| | | |
| | | // 卿å®çæ§½å表ä¸ï¼è·åä¸ä¸ªæå®ç©æç±»å(G1,G2,G1&G2)çç©ºæ§½ä½ |
| | | // 卿å®çæ§½å表ä¸ï¼è·åä¸ä¸ªæå®ç©æç±»å(G1,G2,G1&G2)çç©ºæ§½ä½ |
| | | CSlot* getAvailableSlotForGlass2(MaterialsType type, const std::vector<int>& candidates); |
| | | |
| | | // è·åä¸ä¸ªæå®ç©æç±»å(G1,G2,G1&G2)çéç©ºæ§½ä½ |
| | | // è·åä¸ä¸ªæå®ç©æç±»å(G1,G2,G1&G2)çéç©ºæ§½ä½ |
| | | CSlot* getNonEmptySlot(MaterialsType type); |
| | | |
| | | // è·åä¸ä¸ªæå®ç©æç±»å(G1,G2,G1&G2)çä¸å·²ç»å å·¥å¤ççæ§½ä½ |
| | | // è·åä¸ä¸ªæå®ç©æç±»å(G1,G2,G1&G2)çä¸å·²ç»å å·¥å¤ççæ§½ä½ |
| | | CSlot* getProcessedSlot(MaterialsType putSlotType, BOOL bJobMode = FALSE); |
| | | CSlot* getProcessedSlot2(MaterialsType putSlotType, const std::vector<int>& candidates); |
| | | CSlot* getInspFailSlot(); |
| | | CSlot* getProcessedSlotCt(unsigned int slot); |
| | | |
| | | // è·åç»çç©æ |
| | | // è·åç»çç©æ |
| | | CGlass* getGlassFromSlot(int slotNo); |
| | | CGlass* getGlassWithCassette(int cassetteSequenceNo, int jobSequenceNo); |
| | | CGlass* getAnyGlass(); |
| | |
| | | int getAllGlass(std::vector<CGlass*>& glasses); |
| | | CJobDataS* getJobDataSWithCassette(int cassetteSequenceNo, int jobSequenceNo); |
| | | |
| | | // éªè¯ç»çåæ§½æ¯å¦å¹é
|
| | | // éªè¯ç»çåæ§½æ¯å¦å¹é
|
| | | BOOL ValidateGlassSlotMatch(); |
| | | |
| | | // æ¯å¦æç»ç |
| | | // æ¯å¦æç»ç |
| | | BOOL hasGlass(); |
| | | BOOL slotHasGlass(int slotIndex = 0); |
| | | |
| | | // æå®æ§½ä½æ¯å¦å¯ä»¥æ¾ç½®ç»ç |
| | | // æå®æ§½ä½æ¯å¦å¯ä»¥æ¾ç½®ç»ç |
| | | BOOL canPlaceGlassInSlot(const short slotIndex); |
| | | |
| | | // æå¨ç§»é¤ç©æ |
| | | // æå¨ç§»é¤ç©æ |
| | | int removeGlass(int slotNo); |
| | | |
| | | // åç¬¦ä¸²æ£æµç»æè½¬æ¢ |
| | | // åç¬¦ä¸²æ£æµç»æè½¬æ¢ |
| | | InspResult judgeStringToInspResult(std::string& strJudge); |
| | | |
| | | // for test |
| | | void fireSetProcessState(int nSlotNo, PROCESS_STATE state) { return setProcessState(nSlotNo, state); } |
| | | |
| | | |
| | | |
| | | // 以ä¸ä¸ºä»CC-Link读åå°çBitæ å¿ä½æ£æµå½æ° |
| | | // 以ä¸ä¸ºä»CC-Link读åå°çBitæ å¿ä½æ£æµå½æ° |
| | | public: |
| | | BOOL isAlive(); |
| | | BOOL isCimOn(); |
| | |
| | | BOOL isLinkSignalUpstreamOn(unsigned int path, unsigned int signal); |
| | | BOOL isLinkSignalDownstreamOn(unsigned int path, unsigned int signal); |
| | | |
| | | // åªå¨æ¨¡ææµè¯æ¶ä½¿ç¨ç彿°ï¼ç¨äºæ¨¡æä¿¡å· |
| | | // åªå¨æ¨¡ææµè¯æ¶ä½¿ç¨ç彿°ï¼ç¨äºæ¨¡æä¿¡å· |
| | | void setLinkSignalUpstream(unsigned int path, unsigned int signal, BOOL bOn); |
| | | void setLinkSignalUpstreamBlock(unsigned int path, BOOL* pSignal); |
| | | void setLinkSignalDownstream(unsigned int path, unsigned int signal, BOOL bOn); |
| | |
| | | float toFloat(const char* pszAddr); |
| | | |
| | | protected: |
| | | // é¨åä¼å/ç®å代ç ãæå®ç°é¨åï¼å°æ¶å¹³éºå¼ |
| | | // é¨åä¼å/ç®å代ç ãæå®ç°é¨åï¼å°æ¶å¹³éºå¼ |
| | | void addFacDataReportStep(int dataDev, int writeSignalDev, int port); |
| | | |
| | | |
| | |
| | | int m_nID; |
| | | std::string m_strName; |
| | | std::string m_strDescription; |
| | | std::string m_currentRecipe; |
| | | CRITICAL_SECTION m_criticalSection; |
| | | StationIdentifier m_station; |
| | | MemoryBlock m_blockReadBit; |
| | |
| | | std::vector<CPin*> m_outputPins; |
| | | |
| | | |
| | | // 以ä¸ä¸ºä»CC-Link读åå°çBitæ å¿ä½ |
| | | // 以ä¸ä¸ºä»CC-Link读åå°çBitæ å¿ä½ |
| | | protected: |
| | | ALIVE m_alive; |
| | | BOOL m_bCimState; // ON/OFF |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "CEventEditDlg.h" |
| | | #include "Servo.h" |
| | | #include "resource.h" |
| | | #include <algorithm> |
| | | |
| | | IMPLEMENT_DYNAMIC(CEventEditDlg, CDialogEx) |
| | | |
| | | CEventEditDlg::CEventEditDlg(const CString& title, int eventId, const CString& name, const CString& desc, const std::vector<unsigned int>& rptIds, CWnd* pParent) |
| | | : CDialogEx(IDD_DIALOG_EVENT_EDIT, pParent) |
| | | , m_strTitle(title) |
| | | , m_eventId(eventId) |
| | | , m_strName(name) |
| | | , m_strDesc(desc) |
| | | , m_rptIds(rptIds) |
| | | { |
| | | } |
| | | |
| | | CEventEditDlg::~CEventEditDlg() |
| | | { |
| | | } |
| | | |
| | | void CEventEditDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_EDIT_EVT_ID, m_editId); |
| | | DDX_Control(pDX, IDC_EDIT_EVT_NAME, m_editName); |
| | | DDX_Control(pDX, IDC_EDIT_EVT_DESC, m_editDesc); |
| | | DDX_Control(pDX, IDC_LIST_EVT_RPTS, m_listRpt); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CEventEditDlg, CDialogEx) |
| | | END_MESSAGE_MAP() |
| | | |
| | | BOOL CEventEditDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | SetWindowText(m_strTitle); |
| | | |
| | | CString strId; |
| | | strId.Format(_T("%d"), m_eventId); |
| | | m_editId.SetWindowText(strId); |
| | | m_editId.SetReadOnly(TRUE); |
| | | m_editName.SetWindowText(m_strName); |
| | | m_editDesc.SetWindowText(m_strDesc); |
| | | |
| | | m_listRpt.SetExtendedStyle(m_listRpt.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES); |
| | | m_listRpt.InsertColumn(0, _T("RPT ID"), LVCFMT_LEFT, 120); |
| | | m_listRpt.InsertColumn(1, _T("VIDs"), LVCFMT_LEFT, 240); |
| | | |
| | | auto& reports = theApp.m_model.m_hsmsPassive.getReports(); |
| | | for (int i = 0; i < (int)reports.size(); ++i) { |
| | | auto rpt = reports[i]; |
| | | if (rpt == nullptr) continue; |
| | | int idx = m_listRpt.InsertItem(m_listRpt.GetItemCount(), std::to_string(rpt->getReportId()).c_str()); |
| | | m_listRpt.SetItemText(idx, 1, rpt->getVariablesIdsText().c_str()); |
| | | m_listRpt.SetItemData(idx, (DWORD_PTR)rpt->getReportId()); |
| | | if (std::find(m_rptIds.begin(), m_rptIds.end(), rpt->getReportId()) != m_rptIds.end()) { |
| | | m_listRpt.SetCheck(idx, TRUE); |
| | | } |
| | | } |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CEventEditDlg::OnOK() |
| | | { |
| | | CString name, desc; |
| | | m_editName.GetWindowText(name); |
| | | m_editDesc.GetWindowText(desc); |
| | | name.Trim(); |
| | | desc.Trim(); |
| | | if (name.IsEmpty()) { |
| | | AfxMessageBox(_T("åç§°ä¸è½ä¸ºç©º")); |
| | | return; |
| | | } |
| | | |
| | | std::vector<unsigned int> selected; |
| | | int count = m_listRpt.GetItemCount(); |
| | | for (int i = 0; i < count; ++i) { |
| | | if (m_listRpt.GetCheck(i)) { |
| | | selected.push_back((unsigned int)m_listRpt.GetItemData(i)); |
| | | } |
| | | } |
| | | if (selected.empty()) { |
| | | AfxMessageBox(_T("è³å°éæ©ä¸ä¸ªReport")); |
| | | return; |
| | | } |
| | | |
| | | m_strName = name; |
| | | m_strDesc = desc; |
| | | m_rptIds.swap(selected); |
| | | CDialogEx::OnOK(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | #include <vector> |
| | | |
| | | // äºä»¶ç¼è¾å¯¹è¯æ¡ï¼æ°å¢/ç¼è¾å
±ç¨ï¼å¾éReportï¼ |
| | | class CEventEditDlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CEventEditDlg) |
| | | |
| | | public: |
| | | CEventEditDlg(const CString& title, int eventId, const CString& name, const CString& desc, const std::vector<unsigned int>& rptIds, CWnd* pParent = nullptr); |
| | | virtual ~CEventEditDlg(); |
| | | |
| | | int GetEventId() const { return m_eventId; } |
| | | CString GetNameText() const { return m_strName; } |
| | | CString GetDescText() const { return m_strDesc; } |
| | | const std::vector<unsigned int>& GetSelectedRptIds() const { return m_rptIds; } |
| | | |
| | | protected: |
| | | virtual BOOL OnInitDialog() override; |
| | | virtual void DoDataExchange(CDataExchange* pDX) override; |
| | | afx_msg void OnOK(); |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | |
| | | private: |
| | | CString m_strTitle; |
| | | int m_eventId; |
| | | CString m_strName; |
| | | CString m_strDesc; |
| | | std::vector<unsigned int> m_rptIds; |
| | | |
| | | CEdit m_editId; |
| | | CEdit m_editName; |
| | | CEdit m_editDesc; |
| | | CListCtrl m_listRpt; |
| | | }; |
| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "CGlass.h" |
| | | #include "Log.h" |
| | | |
| | |
| | | if (s.size() > maxLen) s.resize(maxLen); |
| | | } |
| | | |
| | | // ââ æ¶é´æ³ & å·¥å
· ââ |
| | | // ç¶ææ¶é´æ³ï¼æé/å¼å§/ç»æ |
| | | void CGlass::markQueued() |
| | | { |
| | | m_state = GlsState::Queued; |
| | |
| | | return strOut; |
| | | } |
| | | |
| | | // ========== SVæ°æ®ç®¡çæ¥å£å®ç° ========== |
| | | |
| | | // ========== SVæ°æ®å£è¢ ========== |
| | | static constexpr size_t MAX_SV_DATA_KEEP = 4800; |
| | | void CGlass::addSVData(int machineId, const std::string& dataType, const SVDataItem& dataItem) { |
| | | m_svDatas[machineId][dataType].push_back(dataItem); |
| | | auto& vec = m_svDatas[machineId][dataType]; |
| | | vec.push_back(dataItem); |
| | | if (vec.size() > MAX_SV_DATA_KEEP) { |
| | | vec.erase(vec.begin(), vec.begin() + (vec.size() - MAX_SV_DATA_KEEP)); |
| | | } |
| | | } |
| | | |
| | | void CGlass::addSVData(int machineId, const std::string& dataType, double value) { |
| | | auto now = std::chrono::system_clock::now(); |
| | | m_svDatas[machineId][dataType].emplace_back(now, value); |
| | | auto& vec = m_svDatas[machineId][dataType]; |
| | | vec.emplace_back(now, value); |
| | | if (vec.size() > MAX_SV_DATA_KEEP) { |
| | | vec.erase(vec.begin(), vec.begin() + (vec.size() - MAX_SV_DATA_KEEP)); |
| | | } |
| | | } |
| | | |
| | | void CGlass::addSVData(int machineId, const std::string& dataType, int64_t timestamp, double value) { |
| | | // å°int64_tæ¶é´æ³è½¬æ¢ä¸ºsystem_clock::time_point |
| | | // int64_tæ¶é´è½¬æsystem_clock::time_point |
| | | std::chrono::system_clock::time_point timePoint{ |
| | | std::chrono::milliseconds(timestamp) // å设timestampæ¯æ¯«ç§ |
| | | // 妿æ¯ç§ï¼ä½¿ç¨ï¼std::chrono::seconds(timestamp) |
| | | std::chrono::milliseconds(timestamp) // timestampç²¾åº¦ï¼æ¯«ç§ |
| | | // 妿éè¦ç²¾åº¦æ´é«ï¼å¯è½è¦ä½¿ç¨å
¶ä»æ¶é´åä½ï¼å¦std::chrono::seconds(timestamp) |
| | | }; |
| | | m_svDatas[machineId][dataType].emplace_back(timePoint, value); |
| | | auto& vec = m_svDatas[machineId][dataType]; |
| | | vec.emplace_back(timePoint, value); |
| | | if (vec.size() > MAX_SV_DATA_KEEP) { |
| | | vec.erase(vec.begin(), vec.begin() + (vec.size() - MAX_SV_DATA_KEEP)); |
| | | } |
| | | } |
| | | |
| | | void CGlass::addSVData(int machineId, const std::string& dataType, const std::vector<SVDataItem>& dataItems) { |
| | | auto& dataList = m_svDatas[machineId][dataType]; |
| | | dataList.insert(dataList.end(), dataItems.begin(), dataItems.end()); |
| | | if (dataList.size() > MAX_SV_DATA_KEEP) { |
| | | dataList.erase(dataList.begin(), dataList.begin() + (dataList.size() - MAX_SV_DATA_KEEP)); |
| | | } |
| | | } |
| | | |
| | | std::vector<SVDataItem> CGlass::getSVData(int machineId, const std::string& dataType) const { |
| | |
| | | auto machineIt = m_svDatas.find(machineId); |
| | | if (machineIt != m_svDatas.end()) { |
| | | machineIt->second.erase(dataType); |
| | | // å¦æè¯¥æºå¨æ²¡æå
¶ä»æ°æ®äºï¼ä¹æ¸
餿ºå¨æ¡ç® |
| | | if (machineIt->second.empty()) { |
| | | m_svDatas.erase(machineIt); |
| | | } |
| | |
| | | #include "Servo.h" |
| | | #include "CHMPropertyDlg.h" |
| | | #include "afxdialogex.h" |
| | | #include "HmTab.h" |
| | | #include <algorithm> |
| | | |
| | | |
| | | // CEquipmentDlg å¯¹è¯æ¡ |
| | |
| | | m_hbrBkgnd = nullptr; |
| | | m_nWndWidth = 0; |
| | | m_nWndHeight = 0; |
| | | m_pTab = nullptr; |
| | | } |
| | | |
| | | CHMPropertyDlg::CHMPropertyDlg(const char* pszTitle, int width, int height) |
| | |
| | | m_nWndWidth = width; |
| | | m_nWndHeight = height; |
| | | m_strTitle = pszTitle; |
| | | m_pTab = nullptr; |
| | | } |
| | | |
| | | CHMPropertyDlg::~CHMPropertyDlg() |
| | |
| | | |
| | | // Tab |
| | | CString strTitle; |
| | | CHmTab* m_pTab = CHmTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd); |
| | | m_pTab = CHmTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd); |
| | | m_pTab->SetPaddingLeft(20); |
| | | m_pTab->SetItemMarginLeft(18); |
| | | for (int i = 0; i < m_pages.size(); i++) { |
| | | m_pages[i]->SetParent(this); |
| | | m_pages[i]->GetWindowText(strTitle); |
| | | m_pages[i]->OnCreateBtns(); |
| | | m_pTab->AddItem(strTitle, i == m_pages.size() - 1); |
| | | } |
| | | m_pTab->SetCurSel(0); |
| | |
| | | void CHMPropertyDlg::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | if (GetDlgItem(IDC_TAB1) == nullptr) return; |
| | | if (m_pTab == nullptr) return; |
| | | Resize(); |
| | | } |
| | | |
| | |
| | | pItem->GetWindowRect(&rcItem); |
| | | pItem->MoveWindow(x2 - rcItem.Width(), y2 - rcItem.Height(), |
| | | rcItem.Width(), rcItem.Height()); |
| | | y2 -= rcItem.Height(); |
| | | y2 -= 12; |
| | | |
| | | // å½åå页æé®ï¼å¦ææï¼ |
| | | int btnY = y2 - rcItem.Height(); |
| | | int btnX = 12; |
| | | y2 -= rcItem.Height() + 12; |
| | | int curIndex = (m_pTab != nullptr) ? m_pTab->GetCurSel() : 0; |
| | | if (curIndex >= 0 && curIndex < (int)m_pages.size()) { |
| | | auto& btnMap = m_pages[curIndex]->getBtns(); |
| | | // æ BTN_ORDER æåº |
| | | std::vector<std::pair<int, CButton*>> ordered; |
| | | for (auto& kv : btnMap) { |
| | | CButton* btn = kv.second; |
| | | if (btn == nullptr || !::IsWindow(btn->GetSafeHwnd())) continue; |
| | | int order = (int)(INT_PTR)::GetProp(btn->GetSafeHwnd(), _T("BTN_ORDER")); |
| | | ordered.emplace_back(order, btn); |
| | | } |
| | | std::sort(ordered.begin(), ordered.end(), [](const auto& a, const auto& b) { |
| | | return a.first < b.first; |
| | | }); |
| | | for (auto& item : ordered) { |
| | | CButton* btn = item.second; |
| | | CRect rcBtn; |
| | | btn->GetWindowRect(&rcBtn); |
| | | if (rcBtn.Width() <= 0 || rcBtn.Height() <= 0) { |
| | | rcBtn.SetRect(0, 0, 80, 28); |
| | | } |
| | | btn->MoveWindow(btnX, btnY, rcBtn.Width(), rcBtn.Height()); |
| | | btnX += rcBtn.Width() + 8; |
| | | } |
| | | } |
| | | |
| | | // åé线 |
| | | pItem = GetDlgItem(IDC_LINE1); |
| | |
| | | for (int i = 0; i < m_pages.size(); i++) { |
| | | m_pages[i]->ShowWindow(i == index ? SW_SHOW : SW_HIDE); |
| | | } |
| | | |
| | | // éèææé¡µé¢çæé® |
| | | for (auto page : m_pages) { |
| | | for (auto& kv : page->getBtns()) { |
| | | CButton* btn = kv.second; |
| | | if (btn != nullptr && ::IsWindow(btn->GetSafeHwnd())) { |
| | | btn->ShowWindow(SW_HIDE); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // å建并æ¾ç¤ºå½å页é¢çæé® |
| | | auto& btns = m_pages[index]->getBtns(); |
| | | if (!btns.empty()) { |
| | | CRect rcClient; |
| | | GetClientRect(&rcClient); |
| | | const int margin = 12; |
| | | const int spacing = 8; |
| | | int x = margin; |
| | | int y = rcClient.bottom - 40; // é¢çåºé¨åºå |
| | | |
| | | // æ BTN_ORDER æåº |
| | | std::vector<std::pair<int, CButton*>> ordered; |
| | | for (auto& kv : btns) { |
| | | CButton* btn = kv.second; |
| | | if (btn == nullptr || !::IsWindow(btn->GetSafeHwnd())) continue; |
| | | int order = (int)(INT_PTR)::GetProp(btn->GetSafeHwnd(), _T("BTN_ORDER")); |
| | | ordered.emplace_back(order, btn); |
| | | } |
| | | std::sort(ordered.begin(), ordered.end(), [](const auto& a, const auto& b) { |
| | | return a.first < b.first; |
| | | }); |
| | | for (auto& item : ordered) { |
| | | CButton* btn = item.second; |
| | | CRect rc; |
| | | btn->GetWindowRect(&rc); |
| | | if (rc.Width() <= 0 || rc.Height() <= 0) { |
| | | rc.SetRect(0, 0, 80, 28); |
| | | } |
| | | btn->MoveWindow(x, y, rc.Width(), rc.Height()); |
| | | btn->ShowWindow(SW_SHOW); |
| | | x += rc.Width() + spacing; |
| | | } |
| | | } |
| | | } |
| | | |
| | | void CHMPropertyDlg::SetWindowSize(int width, int height) |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | BOOL CHMPropertyDlg::OnCommand(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | UINT code = HIWORD(wParam); |
| | | HWND hCtrl = (HWND)lParam; |
| | | |
| | | if (code == BN_CLICKED && hCtrl != nullptr) { |
| | | for (auto page : m_pages) { |
| | | for (auto& kv : page->getBtns()) { |
| | | if (kv.second != nullptr && kv.second->GetSafeHwnd() == hCtrl) { |
| | | page->HandleBtnClick(hCtrl); |
| | | return TRUE; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return CDialogEx::OnCommand(wParam, lParam); |
| | | } |
| | |
| | | #pragma once |
| | | #include <vector> |
| | | #include "CHMPropertyPage.h" |
| | | #include "HmTab.h" |
| | | |
| | | |
| | | // CEquipmentDlg å¯¹è¯æ¡ |
| | |
| | | std::vector<CHMPropertyPage*> m_pages; |
| | | int m_nWndWidth; |
| | | int m_nWndHeight; |
| | | CHmTab* m_pTab; |
| | | |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | |
| | | afx_msg void OnTabSelChanged(NMHDR* nmhdr, LRESULT* result); |
| | | afx_msg void OnBnClickedOk(); |
| | | afx_msg void OnBnClickedButtonApply(); |
| | | virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); |
| | | }; |
| | |
| | | { |
| | | |
| | | } |
| | | |
| | | void CHMPropertyPage::OnCreateBtns() |
| | | { |
| | | |
| | | } |
| | | |
| | | CButton* CHMPropertyPage::CreateBtn(const char* name, int w, int h, const UINT id) |
| | | { |
| | | std::string key = std::string(name); |
| | | auto it = m_btns.find(key); |
| | | if (it != m_btns.end()) { |
| | | return it->second; |
| | | } |
| | | |
| | | CButton* pBtn = new CButton(); |
| | | pBtn->Create(name, WS_CHILD, CRect(0, 0, w, h), GetParent(), id); |
| | | // 使ç¨é»è®¤GUIåä½ |
| | | HFONT hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); |
| | | if (hFont != nullptr) { |
| | | pBtn->SetFont(CFont::FromHandle(hFont), FALSE); |
| | | } |
| | | ::SetProp(pBtn->GetSafeHwnd(), _T("BTN_ORDER"), (HANDLE)(INT_PTR)m_btnOrderSeq++); |
| | | m_btns[key] = pBtn; |
| | | return pBtn; |
| | | } |
| | | |
| | | CButton* CHMPropertyPage::GetBtnByName(const char* name) |
| | | { |
| | | auto it = m_btns.find(std::string(name)); |
| | | if (it != m_btns.end()) { |
| | | return it->second; |
| | | } |
| | | return nullptr; |
| | | } |
| | | |
| | | std::map<std::string, CButton*>& CHMPropertyPage::getBtns() |
| | | { |
| | | return m_btns; |
| | | } |
| | | |
| | | void CHMPropertyPage::HandleBtnClick(HWND hBtn) |
| | | { |
| | | for (auto& kv : m_btns) { |
| | | if (kv.second != nullptr && kv.second->GetSafeHwnd() == hBtn) { |
| | | OnClickedBtn(kv.first.c_str()); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CHMPropertyPage, CDialogEx) |
| | | ON_WM_DESTROY() |
| | | END_MESSAGE_MAP() |
| | | |
| | | void CHMPropertyPage::OnDestroy() |
| | | { |
| | | CDialogEx::OnDestroy(); |
| | | |
| | | for (auto& kv : m_btns) { |
| | | CButton* btn = kv.second; |
| | | if (btn != nullptr) { |
| | | if (::IsWindow(btn->GetSafeHwnd())) { |
| | | ::RemoveProp(btn->GetSafeHwnd(), _T("BTN_ORDER")); |
| | | } |
| | | if (::IsWindow(btn->GetSafeHwnd())) { |
| | | btn->DestroyWindow(); |
| | | } |
| | | delete btn; |
| | | } |
| | | } |
| | | m_btns.clear(); |
| | | } |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include <map> |
| | | #include <string> |
| | | |
| | | class CHMPropertyPage : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CHMPropertyPage) |
| | | |
| | | public: |
| | | CHMPropertyPage(UINT nID, CWnd* pPage); // æ åæé 彿° |
| | | virtual ~CHMPropertyPage(); // ææå½æ° |
| | | CHMPropertyPage(UINT nID, CWnd* pPage); // æ åæé 彿° |
| | | virtual ~CHMPropertyPage(); // ææå½æ° |
| | | virtual void OnApply(); |
| | | virtual void OnCreateBtns(); |
| | | afx_msg void OnDestroy(); |
| | | std::map<std::string, CButton*>& getBtns(); |
| | | CButton* GetBtnByName(const char* name); |
| | | void HandleBtnClick(HWND hBtn); |
| | | |
| | | protected: |
| | | // åç±»å¯éåï¼æ°å¢/å é¤/ç¼è¾æé®ç¹å»å¤ç |
| | | virtual void OnClickedBtn(const char* btnName) {}; |
| | | |
| | | protected: |
| | | CButton* CreateBtn(const char* name, int w, int h, const UINT id); |
| | | std::map<std::string, CButton*> m_btns; |
| | | int m_btnOrderSeq{ 0 }; |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | }; |
| | | |
| | |
| | | #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; |
| | |
| | | portStatusReport.setCassetteId("CID1001"); |
| | | int nRet = portStatusReport.serialize(szBuffer, 64); |
| | | decodePortStatusReport(pStep, szBuffer, 64); |
| | | LOGI("<CLoadPort>Port1è½½å
¥æ¨¡ææ°æ®ï¼ id:CID1001 map: 0xf"); |
| | | } |
| | | } |
| | | if (m_nIndex == 1) { |
| | |
| | | portStatusReport.setCassetteId("CID1004"); |
| | | int nRet = portStatusReport.serialize(szBuffer, 64); |
| | | decodePortStatusReport(pStep, szBuffer, 64); |
| | | LOGI("<CLoadPort>Port2è½½å
¥æ¨¡ææ°æ®ï¼ id:CID1004 map: 0xff"); |
| | | } |
| | | } |
| | | */ |
| | |
| | | std::string& CLoadPort::getCassetteId() |
| | | { |
| | | return m_portStatusReport.getCassetteId(); |
| | | } |
| | | |
| | | void CLoadPort::simulateSetCassetteId(const char* pszCarrierId) |
| | | { |
| | | m_portStatusReport.setCassetteId(pszCarrierId); |
| | | } |
| | | |
| | | int CLoadPort::getLoadingCassetteType() |
| | |
| | | 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); |
| | | |
| | | // æåºå°åºç¨å±åæç¤º |
| | | if (m_listener.onMapMismatch != nullptr) { |
| | | m_listener.onMapMismatch(this, scanMap, downloadMap); |
| | | } |
| | | } |
| | | } |
| | | else { |
| | | // æåºå°åºç¨å±åéæ©è¦å å·¥ççå |
| | | // çæç»çåè¡¨ï¼æ¥èª EFEM æ«æå°ç map |
| | | 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(); |
| | |
| | | int getPortStatus(); |
| | | int getCassetteSequenceNo(); |
| | | std::string& getCassetteId(); |
| | | // Simulation helper: allow setting CarrierID when no EFEM is connected. |
| | | void simulateSetCassetteId(const char* pszCarrierId); |
| | | int getLoadingCassetteType(); |
| | | int getQTimeFlag(); |
| | | int getCassetteMappingState(); |
| | |
| | | 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; |
| | | }; |
| | | } |
| | | |
| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "Common.h" |
| | | #include "CMaster.h" |
| | | #include <future> |
| | | #include <vector> |
| | | #include <algorithm> |
| | | #include "RecipeManager.h" |
| | | #include <fstream> |
| | | #include "SerializeUtil.h" |
| | | #include "CServoUtilsTool.h" |
| | | #include "AlarmManager.h" |
| | | #include "ToolUnits.h" |
| | | #include "Model.h" |
| | | |
| | | |
| | | namespace SERVO { |
| | |
| | | m_ullStartTime = 0; |
| | | m_ullRunTime = 0; |
| | | m_state = MASTERSTATE::READY; |
| | | m_curveMode = CurveMode::Production; |
| | | m_pActiveRobotTask = nullptr; |
| | | m_nLastError = ER_CODE_NOERROR; |
| | | m_isCompareMapsBeforeProceeding = FALSE; |
| | |
| | | m_nContinuousWorkingPort = 0; |
| | | m_nContinuousWorkingSlot = 0; |
| | | m_pControlJob = nullptr; |
| | | m_bPauseAlarmRaised = false; |
| | | m_pModelCtx = nullptr; |
| | | m_nTestFlag = 0; |
| | | InitializeCriticalSection(&m_criticalSection); |
| | | } |
| | | |
| | | CMaster::~CMaster() |
| | | { |
| | | // éæ¾Jobç¸å
³ |
| | | // éæ¾Jobç¸å
³ |
| | | for (auto item : m_processJobs) { |
| | | delete item; |
| | | } |
| | |
| | | m_hEventDispatchThreadExit[1] = nullptr; |
| | | } |
| | | |
| | | |
| | | DeleteCriticalSection(&m_criticalSection); |
| | | } |
| | | |
| | | void CMaster::setListener(MasterListener listener) |
| | | { |
| | | m_listener = listener; |
| | | } |
| | | |
| | | void CMaster::setModelCtx(CModel* pModel) |
| | | { |
| | | m_pModelCtx = pModel; |
| | | } |
| | | |
| | | CRobotTask* CMaster::getActiveRobotTask() |
| | |
| | | |
| | | int CMaster::init() |
| | | { |
| | | LOGI("<Master>æ£å¨åå§å..."); |
| | | const ULONGLONG boot_master_begin = GetTickCount64(); |
| | | LOGI("<Master>æ£å¨åå§å..."); |
| | | LOGI("[BOOT][MASTER] init begin"); |
| | | |
| | | |
| | | // cclink |
| | | if (m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1)) != 0) { |
| | | LOGE("è¿æ¥CC-Link失败."); |
| | | const ULONGLONG boot_cclink_begin = GetTickCount64(); |
| | | const int cc_ret = m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1)); |
| | | LOGI("[BOOT][MASTER] CC-Link connect ret=%d, cost=%llu ms", |
| | | cc_ret, |
| | | (unsigned long long)(GetTickCount64() - boot_cclink_begin)); |
| | | if (cc_ret != 0) { |
| | | LOGE("è¿æ¥CC-Link失败."); |
| | | } |
| | | else { |
| | | LOGI("è¿æ¥CC-Linkæå."); |
| | | LOGI("è¿æ¥CC-Linkæå."); |
| | | BoardVersion version{}; |
| | | int nRet = m_cclink.GetBoardVersion(version); |
| | | if (nRet == 0) { |
| | | LOGD("çæ¬ä¿¡æ¯ï¼%s.", version.toString().c_str()); |
| | | LOGD("çæ¬ä¿¡æ¯ï¼%s.", version.toString().c_str()); |
| | | } |
| | | else { |
| | | LOGE("è·åCC-Linkçæ¬ä¿¡æ¯å¤±è´¥."); |
| | | LOGE("è·åCC-Linkçæ¬ä¿¡æ¯å¤±è´¥."); |
| | | } |
| | | |
| | | BoardStatus status; |
| | | nRet = m_cclink.GetBoardStatus(status); |
| | | if (nRet == 0) { |
| | | LOGD("ç¶æï¼%s.", status.toString().c_str()); |
| | | LOGD("ç¶æï¼%s.", status.toString().c_str()); |
| | | } |
| | | else { |
| | | LOGE("è·åCC-Linkç¶æå¤±è´¥."); |
| | | LOGE("è·åCC-Linkç¶æå¤±è´¥."); |
| | | } |
| | | } |
| | | |
| | | |
| | | // åå§åæ·»å ååè®¾å¤ |
| | | // åå§åæ·»å ååè®¾å¤ |
| | | CLoadPort* pPort1, * pPort2, * pPort3, * pPort4; |
| | | CBonder* pBonder1, * pBonder2; |
| | | CEFEM* pEfem; |
| | |
| | | |
| | | |
| | | |
| | | // 读ç¼åæ°æ® |
| | | // 读ç¼åæ°æ® |
| | | const ULONGLONG boot_cache_begin = GetTickCount64(); |
| | | const ULONGLONG boot_read_begin = GetTickCount64(); |
| | | readCache(); |
| | | LOGI("[BOOT][MASTER] readCache finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_read_begin)); |
| | | |
| | | const ULONGLONG boot_state_begin = GetTickCount64(); |
| | | loadState(); |
| | | LOGI("[BOOT][MASTER] loadState finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_state_begin)); |
| | | if (m_listener.onControlJobChanged) { |
| | | notifyControlJobChanged(); |
| | | } |
| | | |
| | | LOGI("[BOOT][MASTER] cache/state loaded, cost=%llu ms (since init %llu ms)", |
| | | (unsigned long long)(GetTickCount64() - boot_cache_begin), |
| | | (unsigned long long)(GetTickCount64() - boot_master_begin)); |
| | | |
| | | |
| | | // 宿¶å¨ |
| | | // 宿¶å¨ |
| | | g_pMaster = this; |
| | | SetTimer(NULL, 1, 250, (TIMERPROC)MasterTimerProc); |
| | | |
| | | |
| | | // è°åº¦çº¿ç¨ |
| | | // è°åº¦çº¿ç¨ |
| | | m_hDispatchThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::DispatchThreadFunction, this, |
| | | 0, &m_nDispatchThreadAddr); |
| | | |
| | | |
| | | // çæ§bitçº¿ç¨ |
| | | // çæ§bitçº¿ç¨ |
| | | m_hReadBitsThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::ReadBitsThreadFunction, this, |
| | | 0, &m_nReadBitsThreadAddr); |
| | | |
| | | |
| | | // æ²çº¿æå¡ |
| | | // æ²çº¿æå¡ |
| | | CreateDAQBridgeServer(); |
| | | |
| | | |
| | | LOGI("<Master>åå§å宿."); |
| | | LOGI("<Master>åå§å宿."); |
| | | LOGI("[BOOT][MASTER] init finished, total cost=%llu ms", |
| | | (unsigned long long)(GetTickCount64() - boot_master_begin)); |
| | | return 0; |
| | | } |
| | | |
| | | void CMaster::setCurveMode(CurveMode mode) |
| | | { |
| | | if (m_curveMode == mode) { |
| | | return; |
| | | } |
| | | m_curveMode = mode; |
| | | if (m_pCollector != nullptr) { |
| | | const uint32_t mids[] = { |
| | | MID_Bonder1, MID_Bonder2, |
| | | MID_VacuumBakeA, MID_VacuumBakeB, |
| | | MID_BakeCoolingA, MID_BakeCoolingB |
| | | }; |
| | | for (uint32_t mid : mids) { |
| | | if (mode == CurveMode::EmptyChamber) { |
| | | m_pCollector->batchStart(mid, "EMPTY_CHAMBER", 30 * 60 * 1000ULL); // 空è
模å¼ï¼å¯å¨éæ ·æ¹æ¬¡ |
| | | } |
| | | else { |
| | | m_pCollector->batchStop(mid); |
| | | m_pCollector->buffersClear(mid); // ååç产模å¼ï¼æ¸
æç©ºè
æ°æ® |
| | | } |
| | | } |
| | | } |
| | | LOGI("<Master>CurveMode=%s", mode == CurveMode::EmptyChamber ? "EmptyChamber" : "Production"); |
| | | } |
| | | |
| | | CurveMode CMaster::getCurveMode() const |
| | | { |
| | | return m_curveMode; |
| | | } |
| | | |
| | | int CMaster::term() |
| | |
| | | ::WaitForSingleObject(m_hEventReadBitsThreadExit[1], INFINITE); |
| | | ::WaitForSingleObject(m_hEventDispatchThreadExit[1], INFINITE); |
| | | |
| | | LOGI("<Master>æ£å¨ç»æç¨åº."); |
| | | LOGI("<Master>æ£å¨ç»æç¨åº."); |
| | | for (auto item : m_listEquipment) { |
| | | item->term(); |
| | | } |
| | |
| | | } |
| | | m_listEquipment.clear(); |
| | | |
| | | // release manual-remove buffer before glass pool is torn down |
| | | for (auto* pGlass : m_bufGlass) { |
| | | if (pGlass != nullptr) { |
| | | pGlass->release(); |
| | | } |
| | | } |
| | | m_bufGlass.clear(); |
| | | |
| | | if (m_pCollector != nullptr) { |
| | | m_pCollector->stopLoop(); |
| | |
| | | |
| | | int CMaster::stop(int nErCode/* = ER_CODE_NOERROR*/) |
| | | { |
| | | // è¿è¡æ¶é´ä¸ºç´¯å ç»æï¼æ¬æ¬¡åæ¢æ¶å·æ°ï¼ |
| | | // è¿è¡æ¶é´ä¸ºç´¯å ç»æï¼æ¬æ¬¡åæ¢æ¶å·æ°ï¼ |
| | | lock(); |
| | | if (m_state != MASTERSTATE::RUNNING && m_state != MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER |
| | | && m_state != MASTERSTATE::RUNNING_BATCH) { |
| | |
| | | unlock(); |
| | | |
| | | |
| | | // æ´æ°ç¶æ |
| | | // æ´æ°ç¶æ |
| | | m_nLastError = nErCode; |
| | | setState(MASTERSTATE::STOPPING); |
| | | |
| | | |
| | | // ControlJobæå |
| | | // ControlJobæå |
| | | lock(); |
| | | if (m_pControlJob != nullptr) { |
| | | m_pControlJob->pause(); |
| | |
| | | |
| | | unsigned CMaster::DispatchProc() |
| | | { |
| | | // ä¼å
èèçç±»å忬¡è¦ç±»å |
| | | // ä¸ç§æ
åµï¼å¦æä¸å主次ï¼ä¸ç´æ¬G1, çå°Bonder1åBonder2齿¾äºG1, Aligner乿¾äºG1, |
| | | // Bonder1åBonder2éè¦çG2å°±è¿ä¸æ¥äº |
| | | // æåºæ¬çå®ç°ï¼å¯ä»¥G2åG2è½®æµæ¬éï¼ä½æå¥½æ ¹æ®Bonderçéæ±æ¥å³å® |
| | | // ä¼å
èèçç±»å忬¡è¦ç±»å |
| | | // ä¸ç§æ
åµï¼å¦æä¸å主次ï¼ä¸ç´æ¬G1, çå°Bonder1åBonder2齿¾äºG1, Aligner乿¾äºG1, |
| | | // Bonder1åBonder2éè¦çG2å°±è¿ä¸æ¥äº |
| | | // æåºæ¬çå®ç°ï¼å¯ä»¥G2åG2è½®æµæ¬éï¼ä½æå¥½æ ¹æ®Bonderçéæ±æ¥å³å® |
| | | MaterialsType primaryType, secondaryType; |
| | | |
| | | |
| | | // åç§æºå¨ |
| | | // åç§æºå¨ |
| | | CLoadPort* pLoadPorts[4]; |
| | | CEFEM* pEFEM = (CEFEM*)getEquipment(EQ_ID_EFEM); |
| | | pLoadPorts[0] = (CLoadPort*)getEquipment(EQ_ID_LOADPORT1); |
| | |
| | | ASSERT(pMeasurement); |
| | | |
| | | while (1) { |
| | | // å¾
éåºä¿¡å·ææ¶é´å° |
| | | // å¾
éåºä¿¡å·ææ¶é´å° |
| | | HANDLE hEvents[] = { m_hEventDispatchThreadExit[0], m_hDispatchEvent }; |
| | | int nRet = WaitForMultipleObjects(2, hEvents, FALSE, 500); |
| | | if (nRet == WAIT_OBJECT_0) { |
| | |
| | | } |
| | | |
| | | |
| | | // å¦æç¶æä¸ºSTARTINGï¼å¼å§å·¥ä½å¹¶åæ¢å°RUNNINGç¶æ |
| | | // å¦æç¶æä¸ºSTARTINGï¼å¼å§å·¥ä½å¹¶åæ¢å°RUNNINGç¶æ |
| | | lock(); |
| | | if (m_state == MASTERSTATE::STARTING) { |
| | | // åéindexerOperationModeChangeå°å个æºå°ï¼æåå忢å°RUNNINGç¶æ |
| | | // å¦å忢å°MSERRORç¶æ |
| | | // åéindexerOperationModeChangeå°å个æºå°ï¼æåå忢å°RUNNINGç¶æ |
| | | // å¦å忢å°MSERRORç¶æ |
| | | int nRet; |
| | | CEquipment* pEq[6] = { pEFEM, pBonder1, pBonder2, pBakeCooling, |
| | | pVacuumBake, pMeasurement}; |
| | |
| | | TRACE("a0001\n", writeCode, retCode); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>EFEM忢Startç¶æå¤±è´¥"); |
| | | LOGE("<Master>EFEM忢Startç¶æå¤±è´¥"); |
| | | m_nLastError = ER_CODE_OPERATION_MODE_FAIL; |
| | | m_strLastError = "EFEM忢Startç¶æå¤±è´¥."; |
| | | m_strLastError = "EFEM忢Startç¶æå¤±è´¥."; |
| | | goto WAIT; |
| | | } |
| | | futures.push_back(promises[0].get_future()); |
| | |
| | | TRACE("a0002\n"); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>Bonder1忢Startç¶æå¤±è´¥"); |
| | | LOGE("<Master>Bonder1忢Startç¶æå¤±è´¥"); |
| | | m_nLastError = ER_CODE_BONDER_OPERATION_MODE_FAIL; |
| | | m_strLastError = "Bonder1忢Startç¶æå¤±è´¥."; |
| | | m_strLastError = "Bonder1忢Startç¶æå¤±è´¥."; |
| | | goto WAIT; |
| | | } |
| | | futures.push_back(promises[1].get_future()); |
| | |
| | | TRACE("a0003\n"); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>Bonder2忢Startç¶æå¤±è´¥"); |
| | | LOGE("<Master>Bonder2忢Startç¶æå¤±è´¥"); |
| | | m_nLastError = ER_CODE_BONDER_OPERATION_MODE_FAIL; |
| | | m_strLastError = "Bonder2忢Startç¶æå¤±è´¥."; |
| | | m_strLastError = "Bonder2忢Startç¶æå¤±è´¥."; |
| | | goto WAIT; |
| | | } |
| | | futures.push_back(promises[2].get_future()); |
| | |
| | | TRACE("a0004\n"); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>BakeCooling忢Startç¶æå¤±è´¥"); |
| | | LOGE("<Master>BakeCooling忢Startç¶æå¤±è´¥"); |
| | | m_nLastError = ER_CODE_OPERATION_MODE_FAIL; |
| | | m_strLastError = "BakeCooling忢Startç¶æå¤±è´¥."; |
| | | m_strLastError = "BakeCooling忢Startç¶æå¤±è´¥."; |
| | | goto WAIT; |
| | | } |
| | | futures.push_back(promises[3].get_future()); |
| | |
| | | TRACE("a0005\n"); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>VacuumBake忢Startç¶æå¤±è´¥"); |
| | | LOGE("<Master>VacuumBake忢Startç¶æå¤±è´¥"); |
| | | m_nLastError = ER_CODE_OPERATION_MODE_FAIL; |
| | | m_strLastError = "VacuumBake忢Startç¶æå¤±è´¥."; |
| | | m_strLastError = "VacuumBake忢Startç¶æå¤±è´¥."; |
| | | goto WAIT; |
| | | } |
| | | futures.push_back(promises[4].get_future()); |
| | |
| | | TRACE("a0006\n"); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>Measurement忢Startç¶æå¤±è´¥"); |
| | | LOGE("<Master>Measurement忢Startç¶æå¤±è´¥"); |
| | | m_nLastError = ER_CODE_OPERATION_MODE_FAIL; |
| | | m_strLastError = "Measurement忢Startç¶æå¤±è´¥."; |
| | | m_strLastError = "Measurement忢Startç¶æå¤±è´¥."; |
| | | goto WAIT; |
| | | } |
| | | futures.push_back(promises[5].get_future()); |
| | |
| | | |
| | | WAIT: |
| | | for (auto& f : futures) { |
| | | f.wait(); // é»å¡çå¾
对åºè®¾å¤å®æ |
| | | f.wait(); // é»å¡çå¾
对åºè®¾å¤å®æ |
| | | } |
| | | for (int i = 0; i < 6; i++) { |
| | | if (!bIomcOk[i]) { |
| | | bIomcOk[6] = FALSE; |
| | | LOGE("<Master>%s忢Startç¶æå¤±è´¥", pEq[i]->getName().c_str()); |
| | | LOGE("<Master>%s忢Startç¶æå¤±è´¥", pEq[i]->getName().c_str()); |
| | | } |
| | | } |
| | | |
| | | // æ£æ¥çæ¯å¦é½å·²ç»åæ¢å°STARTç¶æ |
| | | // æ£æ¥çæ¯å¦é½å·²ç»åæ¢å°STARTç¶æ |
| | | if (!bIomcOk[6]) { |
| | | unlock(); |
| | | setState(MASTERSTATE::MSERROR); |
| | |
| | | } |
| | | |
| | | |
| | | // å¤ç宿å½åäºå¡åï¼åæ¢å°åæ¢æå°±ç»ªç¶æ |
| | | // å¤ç宿å½åäºå¡åï¼åæ¢å°åæ¢æå°±ç»ªç¶æ |
| | | else if (m_state == MASTERSTATE::STOPPING) { |
| | | unlock(); |
| | | LOGI("<Master>å¼å§åæ¢å设å¤å° Stop 模å¼..."); |
| | | LOGI("<Master>å¼å§åæ¢å设å¤å° Stop 模å¼..."); |
| | | |
| | | std::vector<std::promise<void>> promises(6); |
| | | std::vector<std::future<void>> futures; |
| | |
| | | TRACE("s000%d: ret=%d\n", i + 1, retCode); |
| | | }); |
| | | if (nRet != 0) { |
| | | LOGE("<Master>%s忢Stopç¶æåé失败", pEq[i]->getName().c_str()); |
| | | LOGE("<Master>%s忢Stopç¶æåé失败", pEq[i]->getName().c_str()); |
| | | m_nLastError = ER_CODE_OPERATION_MODE_FAIL; |
| | | m_strLastError = pEq[i]->getName() + "忢Stopç¶æåé失败."; |
| | | m_strLastError = pEq[i]->getName() + "忢Stopç¶æåé失败."; |
| | | bIomcOk[i] = FALSE; |
| | | promises[i].set_value(); // é¿å
wait é»å¡ |
| | | promises[i].set_value(); // é¿å
wait é»å¡ |
| | | } |
| | | futures.push_back(promises[i].get_future()); |
| | | } |
| | | |
| | | for (auto& f : futures) { |
| | | f.wait(); // çå¾
ææå®æ |
| | | f.wait(); // çå¾
ææå®æ |
| | | } |
| | | |
| | | for (int i = 0; i < 6; ++i) { |
| | | if (!bIomcOk[i]) { |
| | | bIomcOk[6] = FALSE; |
| | | LOGE("<Master>%s忢Stopç¶æå¤±è´¥", pEq[i]->getName().c_str()); |
| | | LOGE("<Master>%s忢Stopç¶æå¤±è´¥", pEq[i]->getName().c_str()); |
| | | } |
| | | } |
| | | |
| | |
| | | continue; |
| | | } |
| | | |
| | | LOGI("<Master>ææè®¾å¤æååæ¢å° Stop 模å¼"); |
| | | LOGI("<Master>ææè®¾å¤æååæ¢å° Stop 模å¼"); |
| | | if(m_nLastError == ER_CODE_NOERROR) |
| | | setState(MASTERSTATE::READY); |
| | | else |
| | |
| | | } |
| | | |
| | | |
| | | // è°åº¦é»è¾å¤ç |
| | | // è°åº¦é»è¾å¤ç |
| | | else if (m_state == MASTERSTATE::RUNNING) { |
| | | // æ£æµå¤ærobotç¶æ |
| | | // æ£æµå¤ærobotç¶æ |
| | | RMDATA& rmd = pEFEM->getRobotMonitoringData(); |
| | | if (rmd.status != ROBOT_STATUS::Idle && rmd.status != ROBOT_STATUS::Run) { |
| | | unlock(); |
| | |
| | | m_pActiveRobotTask->place(); |
| | | } |
| | | unlock(); |
| | | // æ£æµå°å½åææ£å¨ä¸åçä»»å¡ï¼ç¡®ä¿å½åä»»å¡å®ææä¸æ¢åç»§ç» |
| | | // LOGI("æ£æµå°å½åææ£å¨ä¸åçä»»å¡ï¼ç¡®ä¿å½åä»»å¡å®ææä¸æ¢åç»§ç»..."); |
| | | // æ£æµå°å½åææ£å¨ä¸åçä»»å¡ï¼ç¡®ä¿å½åä»»å¡å®ææä¸æ¢åç»§ç» |
| | | // LOGI("æ£æµå°å½åææ£å¨ä¸åçä»»å¡ï¼ç¡®ä¿å½åä»»å¡å®ææä¸æ¢åç»§ç»..."); |
| | | continue; |
| | | } |
| | | |
| | | |
| | | // Bonder1ãBonder2ãFliperãVacuumBakeãAlignerï¼ç»è®¡G2åG1çæ°é, é
å¯¹ç»æ°, å¤åºçç±»å |
| | | // Bonder1ãBonder2ãFliperãVacuumBakeãAlignerï¼ç»è®¡G2åG1çæ°é, é
å¯¹ç»æ°, å¤åºçç±»å |
| | | int nG2Count = 0, nG1Count = 0, nGlassGroup, nExtraType; |
| | | if (pBonder1->slotHasGlass(0)) { |
| | | nG2Count++; |
| | |
| | | |
| | | |
| | | // Measurement NG -> LoadPort |
| | | // NGååä½ |
| | | // NGååä½ |
| | | if (!rmd.armState[1]) { |
| | | m_pActiveRobotTask = createTransferTask_restore(pMeasurement, pLoadPorts); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | |
| | | } |
| | | |
| | | |
| | | // BakeCoolingå
é¨ |
| | | // BakeCoolingå
é¨ |
| | | // Bake -> Cooling |
| | | if (!rmd.armState[0]) { |
| | | m_pActiveRobotTask = createTransferTask_bake_to_cooling(pBakeCooling); |
| | |
| | | continue; |
| | | } |
| | | |
| | | // æ¹å¤ç模å¼ï¼æç»ä»¥æ¤ä¸ºåï¼ä½å
ä¿çä¹åçåçæ¨¡å¼ |
| | | // æ¹å¤ç模å¼ï¼æç»ä»¥æ¤ä¸ºåï¼ä½å
ä¿çä¹åçåçæ¨¡å¼ |
| | | else if (m_state == MASTERSTATE::RUNNING_BATCH) { |
| | | // 1) æ§å¶ä½ä¸çå½å¨æä¿é |
| | | // 1) æ§å¶ä½ä¸çå½å¨æä¿é |
| | | if (m_pControlJob == nullptr) { unlock(); continue; } |
| | | CJState cjst = m_pControlJob->state(); |
| | | if (cjst == CJState::Completed || cjst == CJState::Aborted || cjst == CJState::Failed) { |
| | |
| | | continue; |
| | | } |
| | | if (cjst == CJState::NoState) { |
| | | LOGI("<Master>ControlJobå·²ç»è¿å
¥åé"); |
| | | LOGI("<Master>ControlJobå·²ç»è¿å
¥åé"); |
| | | m_pControlJob->queue(); |
| | | } |
| | | if (m_pControlJob->state() == CJState::Queued) { |
| | | LOGI("<Master>ControlJobå·²ç»å¯å¨"); |
| | | LOGI("<Master>ControlJobå·²ç»å¯å¨"); |
| | | m_pControlJob->start(); |
| | | if (m_listener.onCjStart) m_listener.onCjStart(this, m_pControlJob); |
| | | } |
| | | if (m_pControlJob->state() == CJState::Paused) { |
| | | LOGI("<Master>ControlJobå·²ç»æ¢å¤è¿è¡"); |
| | | LOGI("<Master>ControlJobå·²ç»æ¢å¤è¿è¡"); |
| | | m_pControlJob->resume(); |
| | | } |
| | | |
| | | // 2) è¥å½åæ PJï¼åéæ©ä¸ä¸ªå¹¶ä¸æ¥ |
| | | // 2) è¥å½åæ PJï¼åéæ©ä¸ä¸ªå¹¶ä¸æ¥ |
| | | if (m_inProcesJobs.empty()) { |
| | | if (auto pj = acquireNextProcessJob()) { |
| | | m_inProcesJobs.push_back(pj); |
| | |
| | | } |
| | | } |
| | | if (m_inProcesJobs.empty()) { |
| | | LOGE("<Master>éæ©å½åProcessJob失败ï¼"); |
| | | LOGE("<Master>éæ©å½åProcessJob失败ï¼"); |
| | | unlock(); |
| | | continue; |
| | | } |
| | | |
| | | // 3) è¥éåæ Glassï¼æåå°çå¾
éå |
| | | // 3) è¥éåæ Glassï¼æåå°çå¾
éå |
| | | if (m_queueGlasses.empty()) { |
| | | int nCount = acquireGlassToQueue(); |
| | | if (nCount > 0) { |
| | | LOGI("<Master>å·²å å
¥ %d åGlasså°å·¥èºåéï¼", nCount); |
| | | LOGI("<Master>å·²å å
¥ %d åGlasså°å·¥èºåéï¼", nCount); |
| | | } |
| | | } |
| | | |
| | | // 4) æºå¨äººç¶æ |
| | | // 4) æºå¨äººç¶æ |
| | | RMDATA& rmd = pEFEM->getRobotMonitoringData(); |
| | | if (rmd.status != ROBOT_STATUS::Idle && rmd.status != ROBOT_STATUS::Run) { |
| | | unlock(); continue; |
| | | } |
| | | |
| | | // 5) æ£å¨æ§è¡ç RobotTask å
让å®è·å®ä¸æ |
| | | // 5) æ£å¨æ§è¡ç RobotTask å
让å®è·å®ä¸æ |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | if (m_pActiveRobotTask->isPicked()) { |
| | | m_pActiveRobotTask->place(); |
| | | } |
| | | unlock(); // çå½åä»»å¡å®ææä¸æ¢åç»§ç» |
| | | unlock(); // çå½åä»»å¡å®ææä¸æ¢åç»§ç» |
| | | continue; |
| | | } |
| | | |
| | | // 6) ââå
³é®ï¼å
¨å±ç»è®¡ G1/G2 ä¸ç»æ°é¨éï¼ä¸åç忝坹é½ï¼ââ |
| | | // 5.5) æåç¶ææ£æ¥ï¼è¥ CJ æå¨å¶ PJ å¤äº Pausedï¼æç¼è°åº¦æ°çæ¬é |
| | | bool pausedByEvent = false; |
| | | if (m_pControlJob != nullptr && m_pControlJob->state() == CJState::Paused) { |
| | | pausedByEvent = true; |
| | | } |
| | | for (auto pj : m_inProcesJobs) { |
| | | if (pj != nullptr && pj->state() == PJState::Paused) { |
| | | pausedByEvent = true; |
| | | break; |
| | | } |
| | | } |
| | | if (!pausedByEvent && m_bPauseAlarmRaised) { |
| | | if (m_pModelCtx != nullptr) { |
| | | m_pModelCtx->clearSoftAlarm(ALID_SOFTWARE_PAUSE_EVENT, 0, 0); |
| | | } |
| | | else { |
| | | AlarmManager& alarmManager = AlarmManager::getInstance(); |
| | | alarmManager.clearAlarmByAttributes(ALID_SOFTWARE_PAUSE_EVENT, 0, 0, CToolUnits::getCurrentTimeString()); |
| | | } |
| | | m_bPauseAlarmRaised = false; |
| | | } |
| | | if (pausedByEvent) { |
| | | LOGI("<Master>è°åº¦æåï¼ControlJob/ProcessJob å¤äº Paused ç¶æï¼å¯è½ç± PauseEvent 触åï¼"); |
| | | unlock(); |
| | | continue; |
| | | } |
| | | |
| | | // 6) ââå
³é®ï¼å
¨å±ç»è®¡ G1/G2 ä¸ç»æ°é¨éï¼ä¸åç忝坹é½ï¼ââ |
| | | auto countG1G2 = [&]() { |
| | | int g1 = 0, g2 = 0; |
| | | if (pBonder1->slotHasGlass(0)) g2++; |
| | |
| | | int nGlassGroup = min(g1Count, g2Count); |
| | | int nExtraType = (g1Count == g2Count ? 0 : (g1Count > g2Count ? 1 : 2)); |
| | | |
| | | // primary/secondary ç»ä¸å®ä¹ï¼secondary é»è®¤ G0ï¼ |
| | | // primary/secondary ç»ä¸å®ä¹ï¼secondary é»è®¤ G0ï¼ |
| | | MaterialsType primaryType = MaterialsType::G1; |
| | | MaterialsType secondaryType = MaterialsType::G0; |
| | | if (nExtraType == 0) primaryType = MaterialsType::G2; // ä¸åç忝ä¸è´ |
| | | if (nExtraType == 0) primaryType = MaterialsType::G2; // ä¸åç忝ä¸è´ |
| | | else primaryType = MaterialsType::G1; |
| | | |
| | | // ç»æ°é¨éï¼â¥2 ç»æ¶ä¸åä» LP ä¸çï¼é¿å
å 积ï¼ä¸åçä¸è´ï¼ |
| | | // ç»æ°é¨éï¼â¥2 ç»æ¶ä¸åä» LP ä¸çï¼é¿å
å 积ï¼ä¸åçä¸è´ï¼ |
| | | bool blockLoadFromLP = (nGlassGroup >= 2); |
| | | |
| | | // 7) Measurement -> LoadPortï¼åºå®ï¼G1 ä¼å
å LPï¼ |
| | | // 7) Measurement -> LoadPortï¼åºå®ï¼G1 ä¼å
å LPï¼ |
| | | if (rmd.armState[0] || rmd.armState[1]) { |
| | | LOGD("Arm1 %s, Arm2 %s.", |
| | | rmd.armState[0] ? _T("ä¸å¯ç¨") : _T("å¯ç¨"), |
| | | rmd.armState[1] ? _T("ä¸å¯ç¨") : _T("å¯ç¨")); |
| | | rmd.armState[0] ? _T("ä¸å¯ç¨") : _T("å¯ç¨"), |
| | | rmd.armState[1] ? _T("ä¸å¯ç¨") : _T("å¯ç¨")); |
| | | } |
| | | for (int s = 0; s < 4; s++) { |
| | | PortType pt = pLoadPorts[s]->getPortType(); |
| | |
| | | BATCH_PORT_PUT: |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | |
| | | // 8) Measurement NG -> LoadPortï¼åä½åéï¼ |
| | | // 8) Measurement NG -> LoadPortï¼åä½åéï¼ |
| | | if (!rmd.armState[1]) { |
| | | m_pActiveRobotTask = createTransferTask_restore(pMeasurement, pLoadPorts); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | |
| | | // 10) BakeCooling å
é¨ï¼Bake -> Coolingï¼ |
| | | // 10) BakeCooling å
é¨ï¼Bake -> Coolingï¼ |
| | | if (!rmd.armState[0]) { |
| | | m_pActiveRobotTask = createTransferTask_bake_to_cooling(pBakeCooling); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | |
| | | // 12) Fliper(G2) -> Bonderï¼åç½®ï¼VacuumBake æ processed G1ï¼è¾åº G2 å° Bonder slot0ï¼ |
| | | // 12) Fliper(G2) -> Bonderï¼åç½®ï¼VacuumBake æ processed G1ï¼è¾åº G2 å° Bonder slot0ï¼ |
| | | if (auto pSrcSlot = pVacuumBake->getProcessedSlot(MaterialsType::G1)) { |
| | | if (!rmd.armState[1] && pBonder1->canPlaceGlassInSlot(0)) { |
| | | m_pActiveRobotTask = createTransferTask(pFliper, pBonder1, MaterialsType::G2, MaterialsType::G0, 2); |
| | |
| | | } |
| | | } |
| | | |
| | | // 13) VacuumBake(G1) -> Bonderï¼æ§½çº§å¤å®ï¼slot0(G2) å·²æä¸ slot1(G1) ä¸ºç©ºï¼ |
| | | // 13) VacuumBake(G1) -> Bonderï¼æ§½çº§å¤å®ï¼slot0(G2) å·²æä¸ slot1(G1) ä¸ºç©ºï¼ |
| | | if (!rmd.armState[0] && pBonder1->slotHasGlass(0) && !pBonder1->slotHasGlass(1)) { |
| | | m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder1, MaterialsType::G1, MaterialsType::G0); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | |
| | | // 14) Aligner -> Fliper(G2) 以å -> VacuumBake(G1)ï¼åºå®æ å°ï¼ |
| | | // 14) Aligner -> Fliper(G2) 以å -> VacuumBake(G1)ï¼åºå®æ å°ï¼ |
| | | if (!rmd.armState[1]) { |
| | | m_pActiveRobotTask = createTransferTask(pAligner, pFliper, MaterialsType::G2, MaterialsType::G0); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | |
| | | // 15) Aligner -> LoadPortï¼restoreï¼ |
| | | // 15) Aligner -> LoadPortï¼restoreï¼ |
| | | if (!rmd.armState[1]) { |
| | | m_pActiveRobotTask = createTransferTask_restore(pAligner, pLoadPorts); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | |
| | | // 16) LoadPort -> Alignerï¼åç»æ°é¨éæ§å¶ï¼ç»ä¸ buddy/ç¶ææ¶åºï¼ |
| | | // 16) LoadPort -> Alignerï¼åç»æ°é¨éæ§å¶ï¼ç»ä¸ buddy/ç¶ææ¶åºï¼ |
| | | if (blockLoadFromLP) { unlock(); continue; } |
| | | |
| | | for (int s = 0; s < 4; s++) { |
| | |
| | | continue; |
| | | } |
| | | |
| | | // ç»ä¸ï¼queue -> start -> setContext -> move queueâinProcess -> onPanelStart |
| | | // ç»ä¸ï¼queue -> start -> setContext -> move queueâinProcess -> onPanelStart |
| | | pGlass->queue(); |
| | | pGlass->start(); |
| | | pEFEM->setContext(pGlass); |
| | | |
| | | bool bMoved = glassFromQueueToInPorcess(pGlass); |
| | | if (bMoved) { |
| | | LOGI("<Master>Glass(%s)ä»çå¾
åéå°å·¥èºåé转移æå.", pGlass->getID().c_str()); |
| | | LOGI("<Master>Glass(%s)ä»çå¾
åéå°å·¥èºåé转移æå.", pGlass->getID().c_str()); |
| | | } |
| | | else { |
| | | LOGE("<Master>Glass(%s)ä»çå¾
åéå°å·¥èºåé转移失败.", pGlass->getID().c_str()); |
| | | LOGE("<Master>Glass(%s)ä»çå¾
åéå°å·¥èºåé转移失败.", pGlass->getID().c_str()); |
| | | } |
| | | |
| | | if (m_listener.onPanelStart) m_listener.onPanelStart(this, pGlass); |
| | |
| | | } |
| | | |
| | | |
| | | // åä¼ æ¨¡å¼è°åº¦é»è¾ |
| | | // åä¼ æ¨¡å¼è°åº¦é»è¾ |
| | | else if (m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) { |
| | | // æ£æµå¤ærobotç¶æ |
| | | // æ£æµå¤ærobotç¶æ |
| | | RMDATA& rmd = pEFEM->getRobotMonitoringData(); |
| | | if (rmd.status != ROBOT_STATUS::Idle && rmd.status != ROBOT_STATUS::Run) { |
| | | unlock(); |
| | |
| | | m_pActiveRobotTask->place(); |
| | | } |
| | | unlock(); |
| | | // æ£æµå°å½åææ£å¨ä¸åçä»»å¡ï¼ç¡®ä¿å½åä»»å¡å®ææä¸æ¢åç»§ç» |
| | | // LOGI("æ£æµå°å½åææ£å¨ä¸åçä»»å¡ï¼ç¡®ä¿å½åä»»å¡å®ææä¸æ¢åç»§ç»..."); |
| | | // æ£æµå°å½åææ£å¨ä¸åçä»»å¡ï¼ç¡®ä¿å½åä»»å¡å®ææä¸æ¢åç»§ç» |
| | | // LOGI("æ£æµå°å½åææ£å¨ä¸åçä»»å¡ï¼ç¡®ä¿å½åä»»å¡å®ææä¸æ¢åç»§ç»..."); |
| | | continue; |
| | | } |
| | | |
| | |
| | | 3, pMeasurement, 0); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | m_nContinuousTransferStep = CTStep_BakeCooling_Measurement; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(BakeCooling -> Measurement)..."); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(BakeCooling -> Measurement)..."); |
| | | } |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | |
| | | |
| | | // BakeCoolingå
é¨ |
| | | // BakeCoolingå
é¨ |
| | | if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_BakeCooling_BakeCooling2) |
| | | && !rmd.armState[0]) { |
| | | m_pActiveRobotTask = createTransferTask_continuous_transfer(pBakeCooling, |
| | | 2, pBakeCooling, 3); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | m_nContinuousTransferStep = CTStep_BakeCooling_BakeCooling3; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(BakeCooling-2 -> BakeCooling-3)..."); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(BakeCooling-2 -> BakeCooling-3)..."); |
| | | } |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | |
| | | 1, pBakeCooling, 2); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | m_nContinuousTransferStep = CTStep_BakeCooling_BakeCooling2; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(BakeCooling-1 -> BakeCooling-2)..."); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(BakeCooling-1 -> BakeCooling-2)..."); |
| | | } |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | |
| | | 0, pBakeCooling, 1); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | m_nContinuousTransferStep = CTStep_BakeCooling_BakeCooling1; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(BakeCooling-0 -> BakeCooling-1)..."); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(BakeCooling-0 -> BakeCooling-1)..."); |
| | | } |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | |
| | | 1, pBakeCooling, 0); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | m_nContinuousTransferStep = CTStep_VacuumBake_BakeCooling; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(VacuumBake(G1) -> BakeCooling)..."); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(VacuumBake(G1) -> BakeCooling)..."); |
| | | } |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | |
| | | 0, pVacuumBake, 1); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | m_nContinuousTransferStep = CTStep_VacuumBake_VacuumBake; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(VacuumBake(G1-0) -> VacuumBake(G1-1))..."); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(VacuumBake(G1-0) -> VacuumBake(G1-1))..."); |
| | | } |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | |
| | | 1, pVacuumBake, 0); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | m_nContinuousTransferStep = CTStep_Bonder2_VacuumBake; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(Bonder2 -> VacuumBake(G1))..."); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(Bonder2 -> VacuumBake(G1))..."); |
| | | } |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | |
| | | 1, pBonder2, 1); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | m_nContinuousTransferStep = CTStep_Bonder1_Bonder2; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(Bonder1 -> Bonder2)..."); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(Bonder1 -> Bonder2)..."); |
| | | } |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | |
| | | 0, pBonder1, 1); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | m_nContinuousTransferStep = CTStep_Fliper_Bonder1; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(Fliper(G2) -> Bonder1)..."); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(Fliper(G2) -> Bonder1)..."); |
| | | } |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | |
| | | 0, pFliper, 0); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | m_nContinuousTransferStep = CTStep_Aligner_Fliper; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(Aligner -> Fliper(G2))..."); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(Aligner -> Fliper(G2))..."); |
| | | } |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | |
| | | m_nContinuousTransferStep = CTStep_LoadPort_Aligner; |
| | | m_nContinuousWorkingPort = p; |
| | | m_nContinuousWorkingSlot = slot; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(LoadPort -> Aligner)..."); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§æ¬éä»»å¡(LoadPort -> Aligner)..."); |
| | | pEFEM->setContext(m_pActiveRobotTask->getContext()); |
| | | goto CT_PORT_GET; |
| | | } |
| | |
| | | CT_PORT_GET: |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | m_nContinuousTransferStep = CTStep_begin; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§ç¬¬ %d è½®", m_nContinuousTransferCount + 1); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼å¼å§ç¬¬ %d è½®", m_nContinuousTransferCount + 1); |
| | | } |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | |
| | |
| | | |
| | | |
| | | // _endthreadex(0); |
| | | TRACE("CMaster::DispatchProc 线ç¨éåº\n"); |
| | | TRACE("CMaster::DispatchProc 线ç¨éåº\n"); |
| | | return 0; |
| | | } |
| | | |
| | | unsigned CMaster::ReadBitsProc() |
| | | { |
| | | // æ å¿ä½æ¸
0å¤ä½ |
| | | // æ å¿ä½æ¸
0å¤ä½ |
| | | { |
| | | StationIdentifier station; |
| | | station.nNetNo = 0; |
| | |
| | | |
| | | |
| | | while (1) { |
| | | // å¾
éåºä¿¡å·ææ¶é´å° |
| | | // å¾
éåºä¿¡å·ææ¶é´å° |
| | | int nRet = ::WaitForSingleObject(m_hEventReadBitsThreadExit[0], 1000); |
| | | if (nRet == WAIT_OBJECT_0) { |
| | | break; |
| | | } |
| | | |
| | | // 读æ å¿ä½ |
| | | // 读æ å¿ä½ |
| | | for (auto item : m_listEquipment) { |
| | | const StationIdentifier& station = item->getStation(); |
| | | MemoryBlock& block = item->getReadBitBlock(); |
| | |
| | | |
| | | |
| | | // _endthreadex(0); |
| | | TRACE("CMaster::ReadBitsProc 线ç¨éåº\n"); |
| | | TRACE("CMaster::ReadBitsProc 线ç¨éåº\n"); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | listener.onPreFethedOutJob = [&](void* pEquipment, int port, CJobDataB* pJobDataB) -> BOOL { |
| | | CEquipment* p = (CEquipment*)pEquipment; |
| | | |
| | | // å¯è½è¦å è¿ä¸å¥ |
| | | // å¯è½è¦å è¿ä¸å¥ |
| | | Sleep(750); |
| | | |
| | | // åçï¼æ´æ°å½åæ¬éä»»å¡ |
| | | // åçï¼æ´æ°å½åæ¬éä»»å¡ |
| | | BOOL bOk = FALSE; |
| | | lock(); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | |
| | | && pJobDataS->getCassetteSequenceNo() == pJobDataB->getCassetteSequenceNo() |
| | | && pJobDataS->getJobSequenceNo() == pJobDataB->getJobSequenceNo()) { |
| | | bOk = TRUE; |
| | | LOGD("<CMaster>onPreFethedOutJob, å·²æ ¡éªæ°æ®ä¸è´æ§."); |
| | | LOGD("<CMaster>onPreFethedOutJob, å·²æ ¡éªæ°æ®ä¸è´æ§."); |
| | | } |
| | | LOGD("<CMaster>onPreFethedOutJob 0004."); |
| | | if (pJobDataS != nullptr) { |
| | |
| | | unlock(); |
| | | |
| | | if (!bOk) { |
| | | LOGE("<CMaster>onPreFethedOutJob, æ°æ®æ ¡éªå¤±è´¥."); |
| | | LOGE("<CMaster>onPreFethedOutJob, æ°æ®æ ¡éªå¤±è´¥."); |
| | | } |
| | | |
| | | return bOk; |
| | |
| | | listener.onPreStoredJob = [&](void* pEquipment, int port, CJobDataB* pJobDataB, short& slot) -> BOOL { |
| | | CEquipment* p = (CEquipment*)pEquipment; |
| | | |
| | | // å¯è½è¦å è¿ä¸å¥ |
| | | // å¯è½è¦å è¿ä¸å¥ |
| | | Sleep(750); |
| | | |
| | | // æ¾çï¼æ´æ°å½åæ¬éä»»å¡ |
| | | // æ¾çï¼æ´æ°å½åæ¬éä»»å¡ |
| | | BOOL bOk = FALSE; |
| | | lock(); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | // æ¯å¦å·²ç»è¿å
¥æè(å³åç宿),è¿å
¥ä¸ä¸æ¥ï¼æ¾ç |
| | | // æ¯å¦å·²ç»è¿å
¥æè(å³åç宿),è¿å
¥ä¸ä¸æ¥ï¼æ¾ç |
| | | if (m_pActiveRobotTask->isPicking() && |
| | | ((m_pActiveRobotTask->getArmNo() == 1 && p->getID() == EQ_ID_ARM_TRAY1) |
| | | || (m_pActiveRobotTask->getArmNo() == 2 && p->getID() == EQ_ID_ARM_TRAY2)) |
| | |
| | | bOk = TRUE; |
| | | } |
| | | |
| | | // æ¯å¦æ¾ç宿 |
| | | // æ¯å¦æ¾ç宿 |
| | | else if (m_pActiveRobotTask->isPlacing() && |
| | | m_pActiveRobotTask->getTarPosition() == p->getID()) { |
| | | CGlass* pGlass = p->getGlassFromSlot(m_pActiveRobotTask->getTarSlot()); |
| | | if (pGlass == nullptr) { |
| | | bOk = TRUE; |
| | | slot = m_pActiveRobotTask->getTarSlot(); |
| | | LOGI("<CMaster>onPreStoredJob, å·²æ ¡éªæ°æ®ä¸è´æ§."); |
| | | LOGI("<CMaster>onPreStoredJob, å·²æ ¡éªæ°æ®ä¸è´æ§."); |
| | | } |
| | | } |
| | | |
| | | // æ¯å¦åæ¤ |
| | | // æ¯å¦åæ¤ |
| | | else if (m_pActiveRobotTask->isRestoring() && |
| | | m_pActiveRobotTask->getSrcPosition() == p->getID()) { |
| | | CGlass* pGlass = p->getGlassFromSlot(m_pActiveRobotTask->getSrcSlot()); |
| | | if (pGlass == nullptr && m_pActiveRobotTask->getSrcSlot() == port) { |
| | | bOk = TRUE; |
| | | slot = m_pActiveRobotTask->getSrcSlot(); |
| | | LOGI("<CMaster>onPreStoredJob, å·²æ ¡éªæ°æ®ä¸è´æ§."); |
| | | LOGI("<CMaster>onPreStoredJob, å·²æ ¡éªæ°æ®ä¸è´æ§."); |
| | | } |
| | | } |
| | | } |
| | | unlock(); |
| | | |
| | | if (!bOk) { |
| | | LOGE("<CMaster>onPreStoredJob, æ°æ®æ ¡éªå¤±è´¥."); |
| | | LOGE("<CMaster>onPreStoredJob, æ°æ®æ ¡éªå¤±è´¥."); |
| | | } |
| | | |
| | | return bOk; |
| | |
| | | m_listener.onEqDataChanged(this, p, 0); |
| | | } |
| | | |
| | | // åæ¾çï¼æ´æ°å½åæ¬éä»»å¡ |
| | | // åæ¾çï¼æ´æ°å½åæ¬éä»»å¡ |
| | | if (code == EDCC_FETCHOUT_JOB) { |
| | | lock(); |
| | | if (m_pActiveRobotTask != nullptr && m_pActiveRobotTask->getSrcPosition() == p->getID()) { |
| | | LOGI("å¼å§åç..."); |
| | | LOGI("å¼å§åç..."); |
| | | } |
| | | unlock(); |
| | | } |
| | |
| | | && ((m_pActiveRobotTask->getArmNo() == 1 && p->getID() == EQ_ID_ARM_TRAY1) |
| | | || (m_pActiveRobotTask->getArmNo() == 2 && p->getID() == EQ_ID_ARM_TRAY2)) |
| | | ) { |
| | | LOGI("åç宿."); |
| | | LOGI("åç宿."); |
| | | m_pActiveRobotTask->fetchOut(); |
| | | m_pActiveRobotTask->picked(); |
| | | } |
| | |
| | | if (m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) { |
| | | if (m_nContinuousTransferStep == CTStep_end) { |
| | | m_nContinuousTransferCount++; |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼ç¬¬ %d è½®ç»æ", m_nContinuousTransferCount); |
| | | LOGI("<ContinuousTransfer>åä¼ æµè¯ï¼ç¬¬ %d è½®ç»æ", m_nContinuousTransferCount); |
| | | if (m_listener.onCTRoundEnd != nullptr) { |
| | | m_listener.onCTRoundEnd(this, m_nContinuousTransferCount); |
| | | } |
| | | } |
| | | } |
| | | |
| | | LOGI("æ¾ç宿..."); |
| | | // å®ææ¤æ¡æ¬éä»»å¡ï¼ä½è¦ææ°æ®åæ¶æ¯ä¸æåºç¨å± |
| | | LOGI("æ¾ç宿..."); |
| | | // å®ææ¤æ¡æ¬éä»»å¡ï¼ä½è¦ææ°æ®åæ¶æ¯ä¸æåºç¨å± |
| | | |
| | | // å¦ææ¯æ¬éåä»AOIæ¬éåPort, åglasså·¥èºå®æ |
| | | // å¦ææ¯æ¬éåä»AOIæ¬éåPort, åglasså·¥èºå®æ |
| | | if (m_pActiveRobotTask->getSrcPosition() == EQ_ID_MEASUREMENT) { |
| | | CGlass* pGlass = (CGlass*)m_pActiveRobotTask->getContext(); |
| | | pGlass->complete(); |
| | |
| | | this->saveState(); |
| | | bool bMoved = glassFromInPorcessToComplete(pGlass); |
| | | if (bMoved) { |
| | | LOGI("<Master>Glass(%s)ä»å·¥èºåéå°å®æåé转移æå.", |
| | | LOGI("<Master>Glass(%s)ä»å·¥èºåéå°å®æåé转移æå.", |
| | | pGlass->getID().c_str()); |
| | | } |
| | | else { |
| | | LOGE("<Master>Glass(%s)ä»å·¥èºåéå°å®æåé转移失败.", |
| | | LOGE("<Master>Glass(%s)ä»å·¥èºåéå°å®æåé转移失败.", |
| | | pGlass->getID().c_str()); |
| | | } |
| | | if (m_listener.onPanelEnd != nullptr) { |
| | | m_listener.onPanelEnd(this, pGlass); |
| | | } |
| | | |
| | | // æ£æ¥PJæ¯å¦å·²ç»å®æ |
| | | // æ£æ¥PJæ¯å¦å·²ç»å®æ |
| | | CProcessJob* pJob = getGlassProcessJob((CGlass*)m_pActiveRobotTask->getContext()); |
| | | if (pJob != nullptr && checkAndUpdatePjComplete(pJob)) { |
| | | this->saveState(); |
| | | LOGE("<Master>ProcessJob(%s)宿.", |
| | | LOGE("<Master>ProcessJob(%s)宿.", |
| | | pJob->id().c_str()); |
| | | processJobFromInPorcessToComplete(pJob); |
| | | if (m_listener.onPjEnd != nullptr) { |
| | | m_listener.onPjEnd(this, pJob); |
| | | } |
| | | |
| | | // æ£æ¥CJæ¯å¦å·²ç»å®æ |
| | | // æ£æ¥CJæ¯å¦å·²ç»å®æ |
| | | ASSERT(m_pControlJob); |
| | | if (checkAndUpdateCjComplete(m_pControlJob)) { |
| | | this->saveState(); |
| | | LOGE("<Master>ControlJob(%s)宿.", |
| | | LOGE("<Master>ControlJob(%s)宿.", |
| | | m_pControlJob->id().c_str()); |
| | | if (m_listener.onCjEnd != nullptr) { |
| | | m_listener.onCjEnd(this, pJob); |
| | |
| | | && m_pActiveRobotTask->getSrcPosition() == p->getID()) { |
| | | m_pActiveRobotTask->stored(); |
| | | m_pActiveRobotTask->restored(); |
| | | LOGI("忤宿..."); |
| | | // å®ææ¤æ¡æ¬éä»»å¡ï¼ä½è¦ææ°æ®åæ¶æ¯ä¸æåºç¨å± |
| | | LOGI("忤宿..."); |
| | | // å®ææ¤æ¡æ¬éä»»å¡ï¼ä½è¦ææ°æ®åæ¶æ¯ä¸æåºç¨å± |
| | | unlock(); |
| | | |
| | | |
| | |
| | | unlock(); |
| | | } |
| | | }; |
| | | listener.onProcessStateChanged = [&](void* pEquipment, int slotNo, PROCESS_STATE state) -> void { |
| | | listener.onProcessStateChanged = [&](void* pEquipment, int slotNo, PROCESS_STATE prevState, PROCESS_STATE state) -> void { |
| | | ASSERT(1 <= slotNo && slotNo <= 8); |
| | | int eqid = ((CEquipment*)pEquipment)->getID(); |
| | | CGlass* pGlass = ((CEquipment*)pEquipment)->getGlassFromSlot(slotNo); |
| | | LOGI("<Master>onProcessStateChanged<%d>", (int)state); |
| | | if (state == PROCESS_STATE::Processing) { |
| | | if (pGlass != nullptr) { |
| | | m_pCollector->batchStart(eqid, |
| | | m_pCollector->batchStart(SlotToMid(eqid, slotNo), |
| | | pGlass->getID().c_str(), 10 * 60 * 1000ULL); |
| | | } |
| | | } |
| | | else if (state == PROCESS_STATE::Complete) { |
| | | m_pCollector->batchStop(eqid); |
| | | if (pGlass != nullptr) { |
| | | m_pCollector->batchStop(SlotToMid(eqid, slotNo)); |
| | | } |
| | | } |
| | | |
| | | if (m_listener.onProcessStateChanged != nullptr) { |
| | | m_listener.onProcessStateChanged(this, (CEquipment*)pEquipment, slotNo, prevState, state); |
| | | } |
| | | }; |
| | | listener.onProcessDataReport = [&](void* pEquipment, const std::vector<CParam>& params) { |
| | | if (m_listener.onProcessDataReport != nullptr) { |
| | | m_listener.onProcessDataReport(this, (CEquipment*)pEquipment, params); |
| | | } |
| | | }; |
| | | listener.onMapMismatch = [&](void* pEquipment, short scanMap, short downMap) { |
| | | LOGE("<Master-%s>Port InUse, map(%d!=%d)ä¸ä¸è´ï¼è¯·æ£æ¥ã", |
| | | LOGE("<Master-%s>Port InUse, map(%d!=%d)ä¸ä¸è´ï¼è¯·æ£æ¥ã", |
| | | ((CEquipment*)pEquipment)->getName().c_str(), scanMap, downMap); |
| | | }; |
| | | listener.onPortStatusChanged = [&](void* pEquipment, short status, __int64 data) { |
| | | LOGE("<Master-%s>onPortStatusChangedãstatus=%d, data=%lld", ((CEquipment*)pEquipment)->getName().c_str(), status); |
| | | LOGE("<Master-%s>onPortStatusChangedãstatus=%d, data=%lld", ((CEquipment*)pEquipment)->getName().c_str(), status); |
| | | if (status == PORT_INUSE && m_pControlJob != nullptr) { |
| | | CLoadPort* pPort = (CLoadPort*)pEquipment; |
| | | auto pjs = m_pControlJob->getPjs(); |
| | |
| | | } |
| | | }; |
| | | listener.onSVDataReport = [&](void* pEquipment, void* pData) { |
| | | const bool allowSvLog = |
| | | (m_state == MASTERSTATE::RUNNING || |
| | | m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER || |
| | | m_state == MASTERSTATE::RUNNING_BATCH || |
| | | m_state == MASTERSTATE::STARTING); |
| | | const bool allowCurve = allowSvLog || (m_curveMode == CurveMode::EmptyChamber); |
| | | if (!allowCurve) { |
| | | return; |
| | | } |
| | | CSVData* pSVData = (CSVData*)pData; |
| | | auto rawData = pSVData->getSVRawData(); |
| | | std::vector<CParam> params; |
| | | ((CEquipment*)pEquipment)->parsingSVData((const char*)rawData.data(), rawData.size(), params); |
| | | |
| | | |
| | | // 以ä¸å å
¥å°æ²çº¿æ°æ®ä¸ |
| | | |
| | | // 以ä¸å å
¥å°æ²çº¿æ°æ®ä¸ |
| | | LOGD("<Master>onSVDataReport 001"); |
| | | |
| | | const int64_t ts = now_ms_epoch(); |
| | | int eqid = ((CEquipment*)pEquipment)->getID(); |
| | | if (eqid == EQ_ID_Bonder1 || eqid == EQ_ID_Bonder2) { |
| | | // å®ä¹ Bonder çç¹å®æ å° |
| | | LOGD("<Master>onSVDataReport 002A"); |
| | | // å®ä¹ Bonder çç¹å®æ å° |
| | | std::vector<std::pair<int, int>> bonderMapping = { |
| | | {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, {7, 7}, |
| | | {8, 8}, {9, 9}, {10, 10}, {11, 11}, {12, 12}, {13, 13}, {14, 14}, {15, 15}, {16, 16} |
| | | }; |
| | | |
| | | CGlass* pGlass = ((CEquipment*)pEquipment)->getGlassFromSlot(0); |
| | | CGlass* pGlass = ((CEquipment*)pEquipment)->getGlassFromSlot(2); |
| | | auto& dataTypes = CServoUtilsTool::getEqDataTypes(); |
| | | auto& bonderTypes = dataTypes[eqid]; |
| | | auto& bonderTypes = dataTypes[SlotToMid(eqid, 2)]; |
| | | for (const auto& mapping : bonderMapping) { |
| | | int paramIndex = mapping.first; |
| | | int channel = mapping.second; |
| | | |
| | | if (paramIndex < params.size() && channel - 1 < bonderTypes.size()) { |
| | | if(m_pCollector != nullptr) |
| | | m_pCollector->buffersPush(eqid, channel, ts, params.at(paramIndex).getDoubleValue()); |
| | | m_pCollector->buffersPush(SlotToMid(eqid, 2), channel, ts, params.at(paramIndex).getDoubleValue()); |
| | | if(pGlass != nullptr) |
| | | pGlass->addSVData(eqid, bonderTypes[channel], ts, params.at(paramIndex).getDoubleValue()); |
| | | pGlass->addSVData(eqid, bonderTypes[channel - 1], ts, params.at(paramIndex).getDoubleValue()); |
| | | } |
| | | } |
| | | } |
| | | else if (eqid == EQ_ID_VACUUMBAKE) { |
| | | // å®ä¹ VACUUMBAKE çç¹å®æ å° |
| | | LOGD("<Master>onSVDataReport 002"); |
| | | // å®ä¹ VACUUMBAKE çç¹å®æ å° |
| | | std::vector<std::pair<int, int>> vacuumMapping = { |
| | | {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, {7, 7}, |
| | | {10, 8}, {11, 9}, {12, 10}, {13, 11}, {14, 12}, {15, 13}, {16, 14} |
| | | }; |
| | | |
| | | CGlass* pGlass = ((CEquipment*)pEquipment)->getGlassFromSlot(0); |
| | | CGlass* pGlass1 = ((CEquipment*)pEquipment)->getGlassFromSlot(1); |
| | | CGlass* pGlass2 = ((CEquipment*)pEquipment)->getGlassFromSlot(2); |
| | | auto& dataTypes = CServoUtilsTool::getEqDataTypes(); |
| | | auto& vacuumbakeTypes = dataTypes[eqid]; |
| | | auto& vacuumbakeTypes = dataTypes[SlotToMid(eqid, 1)]; |
| | | LOGD("<Master>onSVDataReport 003 : %d", vacuumMapping.size()); |
| | | for (const auto& mapping : vacuumMapping) { |
| | | int paramIndex = mapping.first; |
| | | int channel = mapping.second; |
| | | |
| | | if (paramIndex < params.size() && channel - 1 < vacuumbakeTypes.size()) { |
| | | if (m_pCollector != nullptr) |
| | | m_pCollector->buffersPush(eqid, channel, ts, params.at(paramIndex).getDoubleValue()); |
| | | if (pGlass != nullptr) |
| | | pGlass->addSVData(eqid, vacuumbakeTypes[channel], ts, params.at(paramIndex).getDoubleValue()); |
| | | if (paramIndex < params.size()) { |
| | | auto& param = params.at(paramIndex); |
| | | double value = param.getDoubleValue(); |
| | | const std::string& paramName = param.getName(); |
| | | const char slotTag = !paramName.empty() ? paramName[0] : '\0'; |
| | | const int typeIndex = (slotTag == 'B') ? (channel - 8) : (channel - 1); |
| | | if (typeIndex < 0 || typeIndex >= (int)vacuumbakeTypes.size()) { |
| | | continue; |
| | | } |
| | | const int pushChannel = typeIndex + 1; |
| | | const std::string& dataType = vacuumbakeTypes[typeIndex]; |
| | | |
| | | if (m_pCollector != nullptr) { |
| | | if (slotTag == 'A') |
| | | m_pCollector->buffersPush(SlotToMid(eqid, 1), pushChannel, ts, value); |
| | | else if (slotTag == 'B') |
| | | m_pCollector->buffersPush(SlotToMid(eqid, 2), pushChannel, ts, value); |
| | | } |
| | | |
| | | // æ ¹æ®è
ä½åç¼åå
¥å¯¹åº Slot çç»ç |
| | | if (pGlass1 != nullptr && !dataType.empty() && slotTag == 'A') |
| | | pGlass1->addSVData(eqid, dataType, ts, value); |
| | | if (pGlass2 != nullptr && !dataType.empty() && slotTag == 'B') |
| | | pGlass2->addSVData(eqid, dataType, ts, value); |
| | | } |
| | | } |
| | | } |
| | | else if (eqid == EQ_ID_BAKE_COOLING) { |
| | | // å®ä¹ BAKE_COOLING çç¹å®æ å° |
| | | LOGD("<Master>onSVDataReport 002B"); |
| | | // å®ä¹ BAKE_COOLING çç¹å®æ å° |
| | | std::vector<std::pair<int, int>> coolingMapping = { |
| | | {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, |
| | | {11, 7}, {12, 8}, {13, 9}, {14, 10}, {15, 11}, {16, 12} |
| | | }; |
| | | |
| | | CGlass* pGlass = ((CEquipment*)pEquipment)->getGlassFromSlot(0); |
| | | CGlass* pGlass1 = ((CEquipment*)pEquipment)->getGlassFromSlot(1); // A Bake |
| | | CGlass* pGlass2 = ((CEquipment*)pEquipment)->getGlassFromSlot(2); // A Cool |
| | | CGlass* pGlass3 = ((CEquipment*)pEquipment)->getGlassFromSlot(3); // B Bake |
| | | CGlass* pGlass4 = ((CEquipment*)pEquipment)->getGlassFromSlot(4); // B Cool |
| | | auto& dataTypes = CServoUtilsTool::getEqDataTypes(); |
| | | auto& coolingTypes = dataTypes[eqid]; |
| | | auto& coolingTypes = dataTypes[SlotToMid(eqid, 1)]; |
| | | LOGD("<Master>onSVDataReport 003B : %d", coolingMapping.size()); |
| | | auto addToGlass = [&](CGlass* glass, const std::string& type, double val) { |
| | | if (glass != nullptr) |
| | | glass->addSVData(eqid, type, ts, val); |
| | | }; |
| | | for (const auto& mapping : coolingMapping) { |
| | | int paramIndex = mapping.first; |
| | | int channel = mapping.second; |
| | | |
| | | if (paramIndex < params.size() && channel - 1 < coolingTypes.size()) { |
| | | if (m_pCollector != nullptr) |
| | | m_pCollector->buffersPush(eqid, channel, ts, params.at(paramIndex).getDoubleValue()); |
| | | if (pGlass != nullptr) |
| | | pGlass->addSVData(eqid, coolingTypes[channel], ts, params.at(paramIndex).getDoubleValue()); |
| | | if (paramIndex < params.size()) { |
| | | auto& param = params.at(paramIndex); |
| | | double value = param.getDoubleValue(); |
| | | const std::string& paramName = param.getName(); |
| | | const char slotTag = !paramName.empty() ? paramName[0] : '\0'; |
| | | const bool paramIsBake = paramName.find("çç¤") != std::string::npos; |
| | | const bool paramIsCooling = paramName.find("å·å´") != std::string::npos; |
| | | const int typeIndex = (slotTag == 'B') ? (channel - 7) : (channel - 1); |
| | | if (typeIndex < 0 || typeIndex >= (int)coolingTypes.size()) { |
| | | continue; |
| | | } |
| | | const int pushChannel = typeIndex + 1; |
| | | const std::string& dataType = coolingTypes[typeIndex]; |
| | | |
| | | if (m_pCollector != nullptr && paramIsBake) { |
| | | if (slotTag == 'A') |
| | | m_pCollector->buffersPush(SlotToMid(eqid, 1), pushChannel, ts, value); |
| | | else if (slotTag == 'B') |
| | | m_pCollector->buffersPush(SlotToMid(eqid, 3), pushChannel, ts, value); |
| | | } |
| | | |
| | | if (!dataType.empty()) { |
| | | switch (slotTag) { |
| | | case 'A': |
| | | if (paramIsBake) |
| | | addToGlass(pGlass1, dataType, value); |
| | | else if (paramIsCooling) |
| | | addToGlass(pGlass2, dataType, value); |
| | | break; |
| | | case 'B': |
| | | if (paramIsBake) |
| | | addToGlass(pGlass3, dataType, value); |
| | | else if (paramIsCooling) |
| | | addToGlass(pGlass4, dataType, value); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 以䏿¯è¾åºæµè¯ |
| | | // 以䏿¯è¾åºæµè¯ |
| | | std::string strOut; |
| | | char szBuffer[256]; |
| | | for (auto p : params) { |
| | |
| | | strOut.append(szBuffer); |
| | | } |
| | | LOGD("<CMaster-%s>SVDataReport:%s", ((CEquipment*)pEquipment)->getName().c_str(), strOut.c_str()); |
| | | |
| | | if (m_listener.onSVDataReport != nullptr) { |
| | | m_listener.onSVDataReport(this, (CEquipment*)pEquipment, params); |
| | | } |
| | | }; |
| | | listener.onPanelDataReport = [&](void* pEquipment, void* pContext) { |
| | | LOGD("<CMaster-%s>onPanelDataReport", ((CEquipment*)pEquipment)->getName().c_str()); |
| | |
| | | CEquipment* pEq = (CEquipment*)pEquipment; |
| | | CGlass* pGlass = (CGlass*)pContext; |
| | | |
| | | // 妿AOIæ£æµå¤±è´¥ï¼è¦åæº |
| | | // 妿AOIæ£æµå¤±è´¥ï¼è¦åæº |
| | | if (pEq->getID() == EQ_ID_MEASUREMENT) { |
| | | LOGD("<CMaster-%s>onPanelDataReport 01", ((CEquipment*)pEquipment)->getName().c_str()); |
| | | if (pGlass->getAOIInspResult() == InspResult::Fail) { |
| | | LOGD("<CMaster-%s>onPanelDataReport 02", ((CEquipment*)pEquipment)->getName().c_str()); |
| | | if (stop() == 0) { |
| | | m_nLastError = ER_CODE_AOI_NG; |
| | | m_strLastError = "AOIæ£æµæªéè¿."; |
| | | m_strLastError = "AOIæ£æµæªéè¿."; |
| | | } |
| | | } |
| | | } |
| | | |
| | | }; |
| | | listener.onReceivedJob = [&](void* pEquipment, int port, CJobDataS* pJobDataS) { |
| | | if (m_listener.onJobReceived != nullptr) { |
| | | m_listener.onJobReceived(this, (CEquipment*)pEquipment, port, pJobDataS); |
| | | } |
| | | }; |
| | | listener.onSentOutJob = [&](void* pEquipment, int port, CJobDataS* pJobDataS) { |
| | | if (m_listener.onJobSentOut != nullptr) { |
| | | m_listener.onJobSentOut(this, (CEquipment*)pEquipment, port, pJobDataS); |
| | | } |
| | | }; |
| | | pEquipment->setListener(listener); |
| | | pEquipment->setCcLink(&m_cclink); |
| | |
| | | } |
| | | |
| | | /* |
| | | * æ·»å LoadPort1 |
| | | * æ·»å LoadPort1 |
| | | * index -- 0~3 |
| | | */ |
| | | CLoadPort* CMaster::addLoadPort(int index) |
| | |
| | | |
| | | |
| | | pEquipment->init(); |
| | | LOGE("已添å â%sâ.", pEquipment->getName().c_str()); |
| | | LOGE("已添å â%sâ.", pEquipment->getName().c_str()); |
| | | |
| | | |
| | | return pEquipment; |
| | |
| | | |
| | | |
| | | pEquipment->init(); |
| | | LOGE("已添å âFliperâ."); |
| | | LOGE("已添å âFliperâ."); |
| | | return pEquipment; |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | pEquipment->init(); |
| | | LOGE("已添å âVacuumBakeâ."); |
| | | LOGE("已添å âVacuumBakeâ."); |
| | | |
| | | return pEquipment; |
| | | } |
| | |
| | | |
| | | |
| | | pEquipment->init(); |
| | | LOGE("已添å âAlignerâ."); |
| | | LOGE("已添å âAlignerâ."); |
| | | |
| | | return pEquipment; |
| | | } |
| | |
| | | |
| | | |
| | | pEquipment->init(); |
| | | LOGE("已添å âEFEM(ROBOT)â."); |
| | | LOGE("已添å âEFEM(ROBOT)â."); |
| | | |
| | | return pEquipment; |
| | | } |
| | |
| | | |
| | | |
| | | pEquipment->init(); |
| | | LOGE("已添å âARMâ."); |
| | | LOGE("已添å âARMâ."); |
| | | |
| | | return pEquipment; |
| | | } |
| | |
| | | |
| | | |
| | | pEquipment->init(); |
| | | LOGE("已添å â%sâ.", pEquipment->getName().c_str()); |
| | | LOGE("已添å â%sâ.", pEquipment->getName().c_str()); |
| | | |
| | | return pEquipment; |
| | | } |
| | | |
| | | /* æ·»å bonder1 æ bonder2 |
| | | /* æ·»å bonder1 æ bonder2 |
| | | * index -- 0, bonder1 |
| | | * index -- 1, bonder2 |
| | | */ |
| | |
| | | |
| | | |
| | | pEquipment->init(); |
| | | LOGE("已添å â%sâ.", pEquipment->getName().c_str()); |
| | | LOGE("已添å â%sâ.", pEquipment->getName().c_str()); |
| | | |
| | | |
| | | return pEquipment; |
| | |
| | | addToEquipmentList(pEquipment); |
| | | |
| | | pEquipment->init(); |
| | | LOGE("已添å âAlignerâ."); |
| | | LOGE("已添å âAlignerâ."); |
| | | |
| | | return pEquipment; |
| | | } |
| | |
| | | addToEquipmentList(pEquipment); |
| | | |
| | | pEquipment->init(); |
| | | LOGE("已添å âMeasurementâ."); |
| | | LOGE("已添å âMeasurementâ."); |
| | | |
| | | return pEquipment; |
| | | } |
| | |
| | | static int i = 0; |
| | | i++; |
| | | |
| | | // èªå¨ä¿åç¼å |
| | | // èªå¨ä¿åç¼å |
| | | if (i % (4 * 2) == 0) { |
| | | if (m_bDataModify) { |
| | | saveCacheAndBackups(); |
| | |
| | | } |
| | | |
| | | |
| | | // æ¨¡ææµè¯ï¼æ æºå¨èæºæ¶ç¨äºèè° EAPï¼ |
| | | // 读å test.iniï¼å½åç®å½æ exe åç®å½ï¼ |
| | | { |
| | | struct SimCfg { |
| | | bool enabled{ false }; |
| | | DWORD intervalMs{ 5000 }; |
| | | int step{ 0 }; |
| | | }; |
| | | auto loadCfg = [&]() -> SimCfg { |
| | | SimCfg cfg; |
| | | |
| | | // æ¨¡ææµè¯ |
| | | // Try INI: current dir, then exe dir |
| | | char iniPath[MAX_PATH] = { 0 }; |
| | | strcpy_s(iniPath, "test.ini"); |
| | | auto readIni = [&](const char* path) -> bool { |
| | | const UINT en = GetPrivateProfileIntA("SimEap", "Enabled", 0, path); |
| | | if (en == 0) return false; // treat as missing/disabled |
| | | cfg.enabled = (en != 0); |
| | | cfg.intervalMs = (DWORD)GetPrivateProfileIntA("SimEap", "IntervalMs", 5000, path); |
| | | cfg.intervalMs = max(500u, cfg.intervalMs); |
| | | cfg.step = (int)GetPrivateProfileIntA("SimEap", "Step", 0, path); |
| | | return true; |
| | | }; |
| | | if (!readIni(iniPath)) { |
| | | char exePath[MAX_PATH] = { 0 }; |
| | | GetModuleFileNameA(NULL, exePath, MAX_PATH); |
| | | char* lastSlash = strrchr(exePath, '\\'); |
| | | if (lastSlash != nullptr) { |
| | | *(lastSlash + 1) = '\0'; |
| | | strcat_s(exePath, "test.ini"); |
| | | readIni(exePath); |
| | | } |
| | | } |
| | | return cfg; |
| | | }; |
| | | |
| | | const SimCfg cfg = loadCfg(); |
| | | if (cfg.enabled) { |
| | | static DWORD lastTick = 0; |
| | | static int lastExecutedStep = -1; |
| | | static bool inited = false; |
| | | static SERVO::CGlass simGlass; |
| | | static SERVO::CVcrEventReport simVcr; |
| | | static SERVO::CProcessJob simPj("PJ1001"); |
| | | static SERVO::CControlJob simCj("CJ5007"); |
| | | |
| | | if (!inited) { |
| | | inited = true; |
| | | simGlass.setID("SIM_PANEL_001"); |
| | | simVcr.getGlassId() = "SIM_PANEL_001"; |
| | | } |
| | | |
| | | DWORD now = GetTickCount(); |
| | | if (lastTick == 0) lastTick = now; |
| | | if ((now - lastTick) < cfg.intervalMs) { |
| | | return; |
| | | } |
| | | lastTick = now; |
| | | |
| | | // åæ¥è§¦åï¼æ¯ä¸ª Step åªæ§è¡ä¸æ¬¡ï¼ä½ æå¨ä¿®æ¹ ini ç Step å¼åä¼å次触å |
| | | const int step = cfg.step; |
| | | if (step <= 0 || step == lastExecutedStep) { |
| | | return; |
| | | } |
| | | lastExecutedStep = step; |
| | | |
| | | // åä¸ä¸ª LoadPort ä½ä¸ºæ¨¡æç®æ |
| | | SERVO::CLoadPort* pLpEq = (SERVO::CLoadPort*)getEquipment(EQ_ID_LOADPORT1); |
| | | |
| | | auto fireLoadPortStatus = [&](short status) { |
| | | pLpEq->simulateSetCassetteId("Test-Cassette-001"); |
| | | if (m_listener.onLoadPortStatusChanged != nullptr && pLpEq != nullptr) { |
| | | m_listener.onLoadPortStatusChanged(this, pLpEq, status, 0); |
| | | } |
| | | }; |
| | | auto fireProcessState = [&](SERVO::CEquipment* pEq, int slotNo, SERVO::PROCESS_STATE st) { |
| | | // Drive equipment state so listeners receive prev/current states consistently. |
| | | if (pEq != nullptr) { |
| | | pEq->fireSetProcessState(slotNo, st); |
| | | } |
| | | }; |
| | | |
| | | LOGI("<Master>SIM_EAP single-step=%d", step); |
| | | switch (step) { |
| | | // ===== ä¸å¡æµç¨æ¥éª¤ï¼1~23ï¼===== |
| | | case 1: // E87_06 Material Arrived(TransferBlock) -> Port Blocked |
| | | fireLoadPortStatus(PORT_BLOCKED); |
| | | break; |
| | | case 2: // E87_03 CarrierID Readed -> Port InUse |
| | | fireLoadPortStatus(PORT_INUSE); |
| | | break; |
| | | case 3: // S1F3 Query CJ Space (Host->EQ) - wait host |
| | | LOGI("<Master>SIM_EAP step3: wait host S1F3"); |
| | | break; |
| | | case 4: // S16F21 Query PJ Space (Host->EQ) - wait host |
| | | LOGI("<Master>SIM_EAP step4: wait host S16F21"); |
| | | break; |
| | | case 5: // S7F19 Query PPID List (Host->EQ) - wait host |
| | | LOGI("<Master>SIM_EAP step5: wait host S7F19"); |
| | | break; |
| | | case 6: // S3F17 ProceedWithCarrier (Host->EQ) - wait host |
| | | LOGI("<Master>SIM_EAP step6: wait host S3F17 ProceedWithCarrier"); |
| | | break; |
| | | case 7: // E87_14 Check SlotMap (设å¤ä¸æ¥/è¿å
¥ WFH) - ç± PORT_INUSE å
é¨è§¦å |
| | | fireLoadPortStatus(PORT_INUSE); |
| | | break; |
| | | case 8: // S3F17 ProceedWithSlotMap (Host->EQ) - wait host |
| | | LOGI("<Master>SIM_EAP step8: wait host S3F17 ProceedWithSlotMap"); |
| | | break; |
| | | case 9: // SlotMap Verify OK (æ¬é¡¹ç®å¨æ¶å° ProceedWithSlotMap å䏿¥) - wait host |
| | | LOGI("<Master>SIM_EAP step9: wait host ProceedWithSlotMap to trigger VerifyOK"); |
| | | break; |
| | | case 10: // Create PJ (Host->EQ) - wait host |
| | | LOGI("<Master>SIM_EAP step10: wait host S16F15 CreateMultiPJ"); |
| | | break; |
| | | case 11: // PJ Queuedï¼æ¬é¡¹ç®å¨å建 PJ å䏿¥ï¼ - wait host |
| | | LOGI("<Master>SIM_EAP step11: wait host CreateMultiPJ to trigger PJ_Queued"); |
| | | break; |
| | | case 12: // Create CJ (Host->EQ) - wait host |
| | | LOGI("<Master>SIM_EAP step12: wait host S14F9 CreateCJ"); |
| | | break; |
| | | case 13: // CJ Start |
| | | if (m_listener.onCjStart != nullptr) m_listener.onCjStart(this, &simCj); |
| | | break; |
| | | case 14: // PJ Start |
| | | if (m_listener.onPjStart != nullptr) m_listener.onPjStart(this, &simPj); |
| | | break; |
| | | case 15: // OCR |
| | | if (m_listener.onEqVcrEventReport != nullptr && pLpEq != nullptr) { |
| | | m_listener.onEqVcrEventReport(this, pLpEq, &simVcr); |
| | | } |
| | | break; |
| | | case 16: // Panel Start |
| | | if (m_listener.onPanelStart != nullptr) m_listener.onPanelStart(this, &simGlass); |
| | | // åæ¶è§¦å䏿¬¡åæºå°å¼å§ï¼ç¤ºä¾ï¼Bonder1, slot 1ï¼ |
| | | fireProcessState(getEquipment(EQ_ID_Bonder1), 1, SERVO::PROCESS_STATE::Processing); |
| | | break; |
| | | case 17: // Panel End |
| | | // åæ¶è§¦å䏿¬¡åæºå°ç»æï¼ç¤ºä¾ï¼Bonder1, slot 1ï¼ |
| | | fireProcessState(getEquipment(EQ_ID_Bonder1), 1, SERVO::PROCESS_STATE::Complete); |
| | | if (m_listener.onPanelEnd != nullptr) m_listener.onPanelEnd(this, &simGlass); |
| | | break; |
| | | case 18: // PJ End |
| | | if (m_listener.onPjEnd != nullptr) m_listener.onPjEnd(this, &simPj); |
| | | break; |
| | | case 19: // CJ End |
| | | if (m_listener.onCjEnd != nullptr) m_listener.onCjEnd(this, &simCj); |
| | | break; |
| | | case 20: // Ready to Release (Port Unload Ready; with prev INUSE will also trigger ReadyToRelease) |
| | | fireLoadPortStatus(PORT_UNLOAD_READY); |
| | | break; |
| | | case 21: // CarrierRelease (Host->EQ) - optional / wait host |
| | | LOGI("<Master>SIM_EAP step21: wait host S3F17 CarrierRelease"); |
| | | break; |
| | | case 22: // Ready to Unload |
| | | fireLoadPortStatus(PORT_UNLOAD_READY); |
| | | break; |
| | | case 23: // Material Removed (and ReadyToLoad) |
| | | fireLoadPortStatus(PORT_LOAD_READY); |
| | | fireLoadPortStatus(PORT_EMPTY); // will also raise LoadPortNotAssoc via Model |
| | | break; |
| | | case 24: { // 模æ SV Dataï¼ç¤ºä¾ï¼Bonder1ï¼ |
| | | SERVO::CEquipment* pEq = getEquipment(EQ_ID_Bonder1); |
| | | if (pEq != nullptr && m_listener.onSVDataReport != nullptr) { |
| | | static int counter = 0; |
| | | ++counter; |
| | | std::vector<CParam> params; |
| | | params.emplace_back("MockSV_Temp", "1", "C", 25 + (counter % 5)); |
| | | params.emplace_back("MockSV_Pressure", "2", "kPa", 100 + (counter % 3)); |
| | | params.emplace_back("MockSV_Speed", "3", "mm/s", 50 + (counter % 7)); |
| | | m_listener.onSVDataReport(this, pEq, params); |
| | | LOGI("<Master>SIM_EAP step24: mock SVData (Bonder1), params=%zu", params.size()); |
| | | } |
| | | break; |
| | | } |
| | | case 25: { // 模æ Process Dataï¼ç¤ºä¾ï¼Bonder1ï¼ |
| | | SERVO::CEquipment* pEq = getEquipment(EQ_ID_Bonder1); |
| | | if (pEq != nullptr && m_listener.onProcessDataReport != nullptr) { |
| | | static int counter = 0; |
| | | ++counter; |
| | | std::vector<CParam> params; |
| | | params.emplace_back("MockProc_CycleTime", "1", "s", 30 + (counter % 4)); |
| | | params.emplace_back("MockProc_MaxTemp", "2", "C", 200 + (counter % 6)); |
| | | params.emplace_back("MockProc_Result", "3", "", (counter % 2) ? 1 : 0); |
| | | m_listener.onProcessDataReport(this, pEq, params); |
| | | LOGI("<Master>SIM_EAP step25: mock ProcessData (Bonder1), params=%zu", params.size()); |
| | | } |
| | | break; |
| | | } |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // æ¨¡ææµè¯ |
| | | /* |
| | | static int aaa = 0; |
| | | aaa++; |
| | |
| | | glassFromQueueToInPorcess(pGlass); |
| | | this->saveState(); |
| | | |
| | | // è¿é䏿¥Panel Startäºä»¶ |
| | | // è¿é䏿¥Panel Startäºä»¶ |
| | | if (m_listener.onPanelStart != nullptr) { |
| | | m_listener.onPanelStart(this, pGlass); |
| | | } |
| | |
| | | glassFromInPorcessToComplete(pGlass); |
| | | this->saveState(); |
| | | |
| | | // è¿é䏿¥Panel Endäºä»¶ |
| | | // è¿é䏿¥Panel Endäºä»¶ |
| | | if (m_listener.onPanelEnd != nullptr) { |
| | | m_listener.onPanelEnd(this, pGlass); |
| | | } |
| | |
| | | if (pJob != nullptr && checkAndUpdatePjComplete(pJob)) { |
| | | processJobFromInPorcessToComplete(pJob); |
| | | this->saveState(); |
| | | LOGE("<Master>ProcessJob(%s)宿.", |
| | | LOGE("<Master>ProcessJob(%s)宿.", |
| | | pJob->id().c_str()); |
| | | if (m_listener.onPjEnd != nullptr) { |
| | | m_listener.onPjEnd(this, pJob); |
| | | } |
| | | |
| | | // æ£æ¥CJæ¯å¦å·²ç»å®æ |
| | | // æ£æ¥CJæ¯å¦å·²ç»å®æ |
| | | ASSERT(m_pControlJob); |
| | | if (checkAndUpdateCjComplete(m_pControlJob)) { |
| | | this->saveState(); |
| | | LOGE("<Master>ControlJob(%s)宿.", |
| | | LOGE("<Master>ControlJob(%s)宿.", |
| | | m_pControlJob->id().c_str()); |
| | | if (m_listener.onCjEnd != nullptr) { |
| | | m_listener.onCjEnd(this, pJob); |
| | |
| | | |
| | | nRet = pLoadPort1->getPin("Out")->connectPin(pAligner->getPin("In1")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥LoadPort1-Fliper失败"); |
| | | LOGE("è¿æ¥LoadPort1-Fliper失败"); |
| | | } |
| | | nRet = pLoadPort2->getPin("Out")->connectPin(pAligner->getPin("In2")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥LoadPort1-Fliper失败"); |
| | | LOGE("è¿æ¥LoadPort1-Fliper失败"); |
| | | } |
| | | |
| | | nRet = pAligner->getPin("Out1")->connectPin(pFliper->getPin("In")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥Aligner-Fliper失败"); |
| | | LOGE("è¿æ¥Aligner-Fliper失败"); |
| | | } |
| | | nRet = pAligner->getPin("Out2")->connectPin(pVacuumBake->getPin("In")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥Aligner-VacuumBake失败"); |
| | | LOGE("è¿æ¥Aligner-VacuumBake失败"); |
| | | } |
| | | |
| | | nRet = pFliper->getPin("Out1")->connectPin(pBonder1->getPin("In1")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥Fliper-Bonder1失败"); |
| | | LOGE("è¿æ¥Fliper-Bonder1失败"); |
| | | } |
| | | nRet = pFliper->getPin("Out2")->connectPin(pBonder2->getPin("In1")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥Fliper-Bonder2失败"); |
| | | LOGE("è¿æ¥Fliper-Bonder2失败"); |
| | | } |
| | | |
| | | nRet = pVacuumBake->getPin("Out1")->connectPin(pBonder1->getPin("In2")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥VacuumBake-Bonder1失败"); |
| | | LOGE("è¿æ¥VacuumBake-Bonder1失败"); |
| | | } |
| | | nRet = pVacuumBake->getPin("Out2")->connectPin(pBonder2->getPin("In2")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥VacuumBake-Bonder2失败"); |
| | | LOGE("è¿æ¥VacuumBake-Bonder2失败"); |
| | | } |
| | | |
| | | nRet = pBonder1->getPin("Out")->connectPin(pBakeCooling->getPin("In1")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥Bonder1-BakeCooling失败"); |
| | | LOGE("è¿æ¥Bonder1-BakeCooling失败"); |
| | | } |
| | | |
| | | nRet = pBonder2->getPin("Out")->connectPin(pBakeCooling->getPin("In2")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥Bonder2-BakeCooling失败"); |
| | | LOGE("è¿æ¥Bonder2-BakeCooling失败"); |
| | | } |
| | | |
| | | nRet = pBakeCooling->getPin("Out")->connectPin(pMeasurement->getPin("In")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥BakeCooling-LoadPort3失败"); |
| | | LOGE("è¿æ¥BakeCooling-LoadPort3失败"); |
| | | } |
| | | |
| | | nRet = pMeasurement->getPin("Out1")->connectPin(pLoadPort3->getPin("In")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥BakeCooling-LoadPort3失败"); |
| | | LOGE("è¿æ¥BakeCooling-LoadPort3失败"); |
| | | } |
| | | |
| | | nRet = pMeasurement->getPin("Out2")->connectPin(pLoadPort4->getPin("In")); |
| | | if (nRet < 0) { |
| | | LOGE("è¿æ¥BakeCooling-LoadPort4失败"); |
| | | LOGE("è¿æ¥BakeCooling-LoadPort4失败"); |
| | | } |
| | | } |
| | | |
| | |
| | | saveCache(); |
| | | |
| | | |
| | | // å建å¤ä»½ç®å½ |
| | | // å建å¤ä»½ç®å½ |
| | | CString strNewFile; |
| | | CString strFileDir = m_strFilepath.c_str(); |
| | | int index = strFileDir.ReverseFind('\\'); |
| | |
| | | } |
| | | unlock(); |
| | | |
| | | // å½å任塿å¨ä¸æ¢åï¼åæ¢è°åº¦ï¼éè¦æä½åå¨è§£å³é®é¢åï¼éæ°å¯å¨ |
| | | // 25å¹´7æ23æ¥åä¿®æ¹ä¸ºä¸åæ¢ä»»å¡ |
| | | // å½å任塿å¨ä¸æ¢åï¼åæ¢è°åº¦ï¼éè¦æä½åå¨è§£å³é®é¢åï¼éæ°å¯å¨ |
| | | // 25å¹´7æ23æ¥åä¿®æ¹ä¸ºä¸åæ¢ä»»å¡ |
| | | // stop(); |
| | | |
| | | return 0; |
| | |
| | | } |
| | | 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; |
| | | |
| | | // æ´æ°context |
| | | 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; |
| | |
| | | |
| | | |
| | | this->saveState(); |
| | | if (m_listener.onControlJobChanged) { |
| | | notifyControlJobChanged(); |
| | | } |
| | | |
| | | return (int)m_processJobs.size(); |
| | | } |
| | |
| | | |
| | | int CMaster::setControlJob(CControlJob& controlJob) |
| | | { |
| | | // åè°ï¼æ¯å¦åå建ControlJob |
| | | // åè°ï¼æ¯å¦åå建ControlJob |
| | | auto canCreateCjFn = [&](uint32_t& cc, std::string& mm) -> bool { |
| | | if (m_pControlJob != nullptr) { |
| | | cc = 1100; |
| | | mm = "å½åControlJobæªç»æ¹ï¼ä¸è½å建æ°çControlJob"; |
| | | mm = "å½åControlJobæªç»æ¹ï¼ä¸è½å建æ°çControlJob"; |
| | | return false; |
| | | } |
| | | return true; |
| | | }; |
| | | |
| | | |
| | | // åè°ï¼æ¯å¦åå¨ |
| | | // åè°ï¼æ¯å¦åå¨ |
| | | auto pjExists = [&](const std::string& id) -> bool { |
| | | return getProcessJob(id) != nullptr; |
| | | }; |
| | | |
| | | // åè°ï¼æ¯å¦å¯å å
¥ CJï¼è¿éå®ä¹ï¼å¿
é¡»æ¯ Queuedï¼ |
| | | // åè°ï¼æ¯å¦å¯å å
¥ CJï¼è¿éå®ä¹ï¼å¿
é¡»æ¯ Queuedï¼ |
| | | auto pjJoinable = [&](const std::string& id) -> bool { |
| | | auto pj = getProcessJob(id); |
| | | if (pj == nullptr) return false; |
| | |
| | | } |
| | | m_pControlJob->setPJs(temps); |
| | | this->saveState(); |
| | | if (m_listener.onControlJobChanged) { |
| | | notifyControlJobChanged(); |
| | | } |
| | | |
| | | |
| | | return 0; |
| | |
| | | |
| | | bool CMaster::ceidDefined(uint32_t ceid) const |
| | | { |
| | | return true; |
| | | if (m_allowedCeids.empty()) return true; // backward compatible: treat as all allowed when not configured |
| | | return m_allowedCeids.find(ceid) != m_allowedCeids.end(); |
| | | } |
| | | |
| | | bool CMaster::raiseSoftAlarm(int alarmId, |
| | | const std::string& desc, |
| | | int level/* = -1*/, |
| | | int deviceId/* = 0*/, |
| | | int unitId/* = 0*/, |
| | | const char* deviceName/* = "Software"*/, |
| | | const char* unitName/* = "App"*/) |
| | | { |
| | | AlarmManager& alarmManager = AlarmManager::getInstance(); |
| | | const AlarmInfo* info = alarmManager.getAlarmInfoByID(alarmId); |
| | | |
| | | int severity = level; |
| | | if (severity < 0 && info != nullptr) { |
| | | severity = info->nAlarmLevel; |
| | | } |
| | | if (severity < 0) severity = 0; // fallback |
| | | |
| | | std::string descText = desc; |
| | | if (descText.empty() && info != nullptr) { |
| | | descText = !info->strDescription.empty() ? info->strDescription : info->strAlarmText; |
| | | } |
| | | if (descText.empty()) { |
| | | descText = CToolUnits::formatString("Alarm %d", alarmId); |
| | | } |
| | | |
| | | AlarmData alarmData; |
| | | alarmData.nId = alarmId; |
| | | alarmData.nSeverityLevel = severity; |
| | | alarmData.nDeviceId = deviceId; |
| | | alarmData.nUnitId = unitId; |
| | | alarmData.strDeviceName = deviceName; |
| | | alarmData.strUnitName = unitName; |
| | | alarmData.strStartTime = CToolUnits::timeToString2(CToolUnits::getTimestamp()); |
| | | alarmData.strEndTime = ""; |
| | | alarmData.strDescription = descText; |
| | | |
| | | int nAlarmEventId = 0; |
| | | return alarmManager.addAlarm(alarmData, nAlarmEventId); |
| | | } |
| | | |
| | | void CMaster::handleCollectionEvent(uint32_t ceid) |
| | | { |
| | | // éåå½å PJï¼å½ä¸ pauseEvents æ¶å¯å¨æ¤æ©å±æåå¨ä½ |
| | | bool pausedAny = false; |
| | | for (auto pj : m_processJobs) { |
| | | if (pj == nullptr) continue; |
| | | const auto& pauseList = pj->pauseEvents(); |
| | | if (std::find(pauseList.begin(), pauseList.end(), ceid) != pauseList.end()) { |
| | | LOGW("<Master>PauseEvent hit: CEID=%u, PJ=%s, state=%d", ceid, pj->id().c_str(), (int)pj->state()); |
| | | if (pj->pause()) { |
| | | LOGI("<Master>PJ paused by CEID=%u", ceid); |
| | | pausedAny = true; |
| | | } |
| | | if (m_pControlJob != nullptr && m_pControlJob->state() == CJState::Executing) { |
| | | if (m_pControlJob->pause()) { |
| | | LOGI("<Master>ControlJob paused by CEID=%u", ceid); |
| | | pausedAny = true; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (pausedAny && m_listener.onControlJobChanged) { |
| | | // éç¥åºç¨å±å·æ° UI/æé®ç¶æ |
| | | notifyControlJobChanged(); |
| | | } |
| | | if (pausedAny && !m_bPauseAlarmRaised) { |
| | | std::string desc = CToolUnits::formatString("<PauseEvent CEID=%u>", ceid); |
| | | bool raised = false; |
| | | if (m_pModelCtx != nullptr) { |
| | | raised = m_pModelCtx->raiseSoftAlarm(ALID_SOFTWARE_PAUSE_EVENT, desc); |
| | | } |
| | | else { |
| | | raised = raiseSoftAlarm(ALID_SOFTWARE_PAUSE_EVENT, desc); |
| | | } |
| | | if (raised) { |
| | | LOGI("<Master>PauseEvent soft alarm raised, CEID=%u", ceid); |
| | | m_bPauseAlarmRaised = true; |
| | | } |
| | | } |
| | | } |
| | | |
| | | void CMaster::setAllowedCeids(const std::vector<unsigned int>& ceids) |
| | | { |
| | | m_allowedCeids.clear(); |
| | | m_allowedCeids.reserve(ceids.size()); |
| | | for (auto id : ceids) { |
| | | m_allowedCeids.insert(id); |
| | | } |
| | | } |
| | | |
| | | bool CMaster::saveState() const |
| | |
| | | std::ofstream ofs(m_strStatePath, std::ios::binary); |
| | | if (!ofs) return false; |
| | | |
| | | // æä»¶å¤´ |
| | | // æä»¶å¤´ |
| | | uint32_t magic = 0x4D415354; // 'MAST' |
| | | uint16_t version = 1; |
| | | ofs.write(reinterpret_cast<const char*>(&magic), sizeof(magic)); |
| | | ofs.write(reinterpret_cast<const char*>(&version), sizeof(version)); |
| | | |
| | | // ä¿å ControlJob |
| | | // ä¿å ControlJob |
| | | bool hasCJ = (m_pControlJob != nullptr); |
| | | ofs.write(reinterpret_cast<const char*>(&hasCJ), sizeof(hasCJ)); |
| | | if (hasCJ) { |
| | | m_pControlJob->serialize(ofs); |
| | | } |
| | | |
| | | // ä¿å ProcessJob å表 |
| | | // ä¿å ProcessJob å表 |
| | | uint32_t count = static_cast<uint32_t>(m_processJobs.size()); |
| | | ofs.write(reinterpret_cast<const char*>(&count), sizeof(count)); |
| | | for (const auto& job : m_processJobs) { |
| | | job->serialize(ofs); |
| | | } |
| | | |
| | | // 以åå¯ä»¥å¨è¿éè¿½å æ°å段 |
| | | // 以åå¯ä»¥å¨è¿éè¿½å æ°å段 |
| | | return true; |
| | | } |
| | | |
| | |
| | | std::ifstream ifs(m_strStatePath, std::ios::binary); |
| | | if (!ifs) return false; |
| | | |
| | | // æä»¶å¤´ |
| | | // æä»¶å¤´ |
| | | uint32_t magic = 0; |
| | | uint16_t version = 0; |
| | | ifs.read(reinterpret_cast<char*>(&magic), sizeof(magic)); |
| | | ifs.read(reinterpret_cast<char*>(&version), sizeof(version)); |
| | | |
| | | if (magic != 0x4D415354) { |
| | | // æä»¶ä¸åæ³ |
| | | // æä»¶ä¸åæ³ |
| | | return false; |
| | | } |
| | | |
| | |
| | | m_pControlJob = nullptr; |
| | | } |
| | | |
| | | // 读å ControlJob |
| | | // 读å ControlJob |
| | | bool hasCJ = false; |
| | | ifs.read(reinterpret_cast<char*>(&hasCJ), sizeof(hasCJ)); |
| | | if (hasCJ) { |
| | |
| | | return false; |
| | | } |
| | | |
| | | // 读å ProcessJob å表 |
| | | // 读å ProcessJob å表 |
| | | uint32_t count = 0; |
| | | ifs.read(reinterpret_cast<char*>(&count), sizeof(count)); |
| | | m_processJobs.clear(); |
| | |
| | | } |
| | | |
| | | |
| | | // æ¾å°CProcessJobæéå å
¥åè¡¨ä¸ |
| | | // æ¾å°CProcessJobæéå å
¥åè¡¨ä¸ |
| | | std::vector<CProcessJob*> tempPjs; |
| | | auto ids = m_pControlJob->pjIds(); |
| | | for (auto id : ids) { |
| | |
| | | m_pControlJob->setPJs(tempPjs); |
| | | |
| | | |
| | | // æ´æ°contexts |
| | | // æ´æ°contexts |
| | | auto pjs = m_pControlJob->getPjs(); |
| | | for (auto pj : pjs) { |
| | | for (auto& c : pj->carriers()) { |
| | |
| | | } |
| | | |
| | | |
| | | // å¦æçæ¬å级ï¼å¯å¨è¿é夿 version æ¥å è½½æ°å段 |
| | | // å¦æçæ¬å级ï¼å¯å¨è¿é夿 version æ¥å è½½æ°å段 |
| | | |
| | | |
| | | return true; |
| | |
| | | CGlass* CMaster::acquireNextGlass() |
| | | { |
| | | for (auto* pj : m_inProcesJobs) { |
| | | // éå PJ ç carriers å slots |
| | | // éå PJ ç carriers å slots |
| | | for (auto& cs : pj->carriers()) { |
| | | for (auto ctx : cs.contexts) { |
| | | CGlass* pGlass = (CGlass*)ctx; |
| | |
| | | } |
| | | } |
| | | } |
| | | return nullptr; // 没æå¯å å·¥ç Glass |
| | | return nullptr; // 没æå¯å å·¥ç Glass |
| | | } |
| | | |
| | | int CMaster::acquireGlassToQueue() |
| | | { |
| | | int nCount = 0; |
| | | for (auto* pj : m_inProcesJobs) { |
| | | // éå PJ ç carriers å slots |
| | | // éå PJ ç carriers å slots |
| | | if (pj->carriers().empty()) continue; |
| | | for (auto& cs : pj->carriers()) { |
| | | for (auto ctx : cs.contexts) { |
| | |
| | | |
| | | |
| | | |
| | | // éæ¾Jobç¸å
³ |
| | | // éæ¾Jobç¸å
³ |
| | | for (auto item : m_processJobs) { |
| | | delete item; |
| | | } |
| | |
| | | m_pControlJob = nullptr; |
| | | } |
| | | |
| | | // 注æè¦éæ¾å¼ç¨ |
| | | // 注æè¦éæ¾å¼ç¨ |
| | | m_inProcesJobs.clear(); |
| | | m_completeProcessJobs.clear(); |
| | | m_queueGlasses.clear(); |
| | |
| | | |
| | | |
| | | saveState(); |
| | | if (m_listener.onControlJobChanged) { |
| | | notifyControlJobChanged(); |
| | | } |
| | | |
| | | return true; |
| | | } |
| | |
| | | m_pControlJob->abort(description); |
| | | |
| | | |
| | | // éæ¾Jobç¸å
³ |
| | | // éæ¾Jobç¸å
³ |
| | | for (auto item : m_processJobs) { |
| | | delete item; |
| | | } |
| | |
| | | m_pControlJob = nullptr; |
| | | } |
| | | |
| | | // 注æè¦éæ¾å¼ç¨ |
| | | // 注æè¦éæ¾å¼ç¨ |
| | | m_inProcesJobs.clear(); |
| | | m_completeProcessJobs.clear(); |
| | | m_queueGlasses.clear(); |
| | |
| | | |
| | | |
| | | saveState(); |
| | | if (m_listener.onControlJobChanged) { |
| | | notifyControlJobChanged(); |
| | | } |
| | | |
| | | return true; |
| | | } |
| | |
| | | { |
| | | if (stop() == 0) { |
| | | m_nLastError = ER_CODE_AOI_NG; |
| | | m_strLastError = "AOIæ£æµæªéè¿."; |
| | | m_strLastError = "AOIæ£æµæªéè¿."; |
| | | } |
| | | } |
| | | |
| | |
| | | if (pSlot == nullptr) return false; |
| | | |
| | | CGlass* pGlass = (CGlass*)pSlot->getContext(); |
| | | if (pGlass == nullptr) return false; |
| | | |
| | | // Buffer ä¸é为 1ï¼æ°æ¬åºæ¶ä¸¢å¼æ§ç |
| | | if (!m_bufGlass.empty()) { |
| | | for (auto* oldGlass : m_bufGlass) { |
| | | if (oldGlass != nullptr) oldGlass->release(); |
| | | } |
| | | m_bufGlass.clear(); |
| | | } |
| | | m_bufGlass.push_back(pGlass); |
| | | pGlass->addRef(); |
| | | pSlot->setContext(nullptr); |
| | |
| | | |
| | | }; |
| | | |
| | | // äºä»¶ï¼æäººè¿å
¥/æå¼å°±ä¸æ¥å¿ |
| | | // äºä»¶ï¼æäººè¿å
¥/æå¼å°±ä¸æ¥å¿ |
| | | auto clieintEventCallback = [](const std::string& ip, uint16_t port, bool connected) { |
| | | LOGI("<DAQBridge>[Client %s] %s:%u", connected ? _T("JOIN") : _T("LEAVE"), ip.c_str(), port); |
| | | }; |
| | |
| | | m_pCollector->createServer(8081); |
| | | m_pCollector->startLoop(10); |
| | | |
| | | // 1) æ³¨åæºå°ï¼æ¨èï¼å
注å id + æºå¨åç§°ï¼ |
| | | // 1) æ³¨åæºå°ï¼æ¨èï¼å
注å id + æºå¨åç§°ï¼ |
| | | RetentionPolicy defP; defP.mode = RetainMode::ByCount; defP.maxSamples = 200; |
| | | m_pCollector->registryAddMachine(EQ_ID_Bonder1, "Bonder1", defP); |
| | | m_pCollector->registryAddMachine(EQ_ID_Bonder2, "Bonder2", defP); |
| | | m_pCollector->registryAddMachine(EQ_ID_VACUUMBAKE, "åçç¤", defP); |
| | | m_pCollector->registryAddMachine(EQ_ID_BAKE_COOLING, "çç¤å·å´", defP); |
| | | m_pCollector->registryAddMachine(MID_Bonder1, "Bonder1", defP); |
| | | m_pCollector->registryAddMachine(MID_Bonder2, "Bonder2", defP); |
| | | m_pCollector->registryAddMachine(MID_VacuumBakeA, "åç-A", defP); |
| | | m_pCollector->registryAddMachine(MID_VacuumBakeB, "åç-B", defP); |
| | | m_pCollector->registryAddMachine(MID_BakeCoolingA, "åç-A", defP); |
| | | m_pCollector->registryAddMachine(MID_BakeCoolingB, "åç-B", defP); |
| | | |
| | | |
| | | // 2) 为ééè®¾ç½®âæ²çº¿åç§°â |
| | | // 2) 为ééè®¾ç½®âæ²çº¿åç§°â |
| | | auto& dataTypes = CServoUtilsTool::getEqDataTypes(); |
| | | auto& bonderTypes = dataTypes[EQ_ID_Bonder1]; |
| | | auto& bonderTypes = dataTypes[MID_Bonder1]; |
| | | for (size_t i = 0; i < bonderTypes.size(); ++i) { |
| | | m_pCollector->buffersSetChannelName(EQ_ID_Bonder1, i + 1, bonderTypes[i].c_str()); |
| | | m_pCollector->buffersSetChannelName(EQ_ID_Bonder2, i + 1, bonderTypes[i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_Bonder1, (UINT)i + 1, bonderTypes[(UINT)i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_Bonder2, (UINT)i + 1, bonderTypes[(UINT)i].c_str()); |
| | | } |
| | | |
| | | auto& vacuumbakeTypes = dataTypes[EQ_ID_VACUUMBAKE]; |
| | | auto& vacuumbakeTypes = dataTypes[MID_VacuumBakeA]; |
| | | for (size_t i = 0; i < vacuumbakeTypes.size(); ++i) { |
| | | m_pCollector->buffersSetChannelName(EQ_ID_VACUUMBAKE, i + 1, vacuumbakeTypes[i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_VacuumBakeA, (UINT)i + 1, vacuumbakeTypes[(UINT)i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_VacuumBakeB, (UINT)i + 1, vacuumbakeTypes[(UINT)i].c_str()); |
| | | } |
| | | |
| | | auto& coolingTypes = dataTypes[EQ_ID_BAKE_COOLING]; |
| | | auto& coolingTypes = dataTypes[MID_BakeCoolingA]; |
| | | for (size_t i = 0; i < coolingTypes.size(); ++i) { |
| | | m_pCollector->buffersSetChannelName(EQ_ID_VACUUMBAKE, i + 1, coolingTypes[i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_BakeCoolingA, i + 1, coolingTypes[i].c_str()); |
| | | m_pCollector->buffersSetChannelName(MID_BakeCoolingB, i + 1, coolingTypes[i].c_str()); |
| | | } |
| | | |
| | | if (m_curveMode == CurveMode::EmptyChamber) { |
| | | const uint32_t mids[] = { |
| | | MID_Bonder1, MID_Bonder2, |
| | | MID_VacuumBakeA, MID_VacuumBakeB, |
| | | MID_BakeCoolingA, MID_BakeCoolingB |
| | | }; |
| | | for (uint32_t mid : mids) { |
| | | m_pCollector->batchStart(mid, "EMPTY_CHAMBER", 10 * 60 * 1000ULL); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | uint32_t CMaster::SlotToMid(int eqid, int slot) |
| | | { |
| | | if (eqid == EQ_ID_Bonder1) { |
| | | return MID_Bonder1; |
| | | } |
| | | |
| | | if (eqid == EQ_ID_Bonder2) { |
| | | return MID_Bonder2; |
| | | } |
| | | |
| | | if (eqid == EQ_ID_VACUUMBAKE) { |
| | | if(slot == 1) |
| | | return MID_VacuumBakeA; |
| | | if (slot == 2) |
| | | return MID_VacuumBakeB; |
| | | } |
| | | |
| | | if (eqid == EQ_ID_BAKE_COOLING) { |
| | | if (slot == 1) |
| | | return MID_BakeCoolingA; |
| | | if (slot == 3) |
| | | return MID_BakeCoolingB; |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | } |
| | |
| | | #pragma once |
| | | #include <list> |
| | | #include <unordered_set> |
| | | #include "CEquipment.h" |
| | | #include "CEFEM.h" |
| | | #include "CBonder.h" |
| | |
| | | #include "ProcessJob.h" |
| | | #include "CControlJob.h" |
| | | #include "../DAQBridge/core/Collector.h" |
| | | #include "CJobDataS.h" |
| | | |
| | | class CModel; |
| | | |
| | | |
| | | #define CTStep_Unknow 0 |
| | |
| | | ATHERERROR |
| | | }; |
| | | |
| | | enum class CurveMode { |
| | | Production = 0, |
| | | EmptyChamber |
| | | }; |
| | | |
| | | typedef std::function<void(void* pMaster, MASTERSTATE state)> ONMASTERSTATECHANGED; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEiuipment, BOOL bAlive)> ONEQALIVE; |
| | | typedef std::function<void(CStep* pStep, int code, void* pData)> ONEQSTEPEVENT; |
| | |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, int code)> ONEQDATACHANGED; |
| | | typedef std::function<void(void* pMaster, CRobotTask* pTask, int code)> ONROBOTTASKEVENT; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, short status, __int64 data)> ONLOADPORTSTATUSCHANGED; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, int slotNo, PROCESS_STATE prevState, PROCESS_STATE state)> ONPROCESSSTATECHANGED; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, const std::vector<CParam>& params)> ONPROCESSDATAREPORTEX; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, const std::vector<CParam>& params)> ONSVDATAREPORT; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, int port, CJobDataS* pJobDataS)> ONJOBRECEIVED; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, int port, CJobDataS* pJobDataS)> ONJOBSENTOUT; |
| | | typedef std::function<void(void* pMaster, int round)> ONCTROUNDEND; |
| | | typedef std::function<void(void* pMaster, void* pj)> ONPJSTART; |
| | | typedef std::function<void(void* pMaster)> ONCONTROLJOBCHANGED; |
| | | typedef struct _MasterListener |
| | | { |
| | | ONMASTERSTATECHANGED onMasterStateChanged; |
| | |
| | | ONEQDATACHANGED onEqDataChanged; |
| | | ONROBOTTASKEVENT onRobotTaskEvent; |
| | | ONLOADPORTSTATUSCHANGED onLoadPortStatusChanged; |
| | | ONPROCESSSTATECHANGED onProcessStateChanged; |
| | | ONSVDATAREPORT onSVDataReport; |
| | | ONPROCESSDATAREPORTEX onProcessDataReport; |
| | | ONJOBRECEIVED onJobReceived; |
| | | ONJOBSENTOUT onJobSentOut; |
| | | ONCTROUNDEND onCTRoundEnd; |
| | | ONPJSTART onCjStart; |
| | | ONPJSTART onCjEnd; |
| | |
| | | ONPJSTART onPjEnd; |
| | | ONPJSTART onPanelStart; |
| | | ONPJSTART onPanelEnd; |
| | | ONCONTROLJOBCHANGED onControlJobChanged; |
| | | } MasterListener; |
| | | |
| | | class CMaster : public IResourceView |
| | |
| | | |
| | | |
| | | public: |
| | | void setModelCtx(CModel* pModel); |
| | | void setListener(MasterListener listener); |
| | | CRobotTask* getActiveRobotTask(); |
| | | int init(); |
| | |
| | | void clearError(); |
| | | ULONGLONG getRunTime(); |
| | | MASTERSTATE getState(); |
| | | void setCurveMode(CurveMode mode); |
| | | CurveMode getCurveMode() const; |
| | | unsigned DispatchProc(); |
| | | unsigned ReadBitsProc(); |
| | | void onTimer(UINT nTimerid); |
| | |
| | | int getPortCassetteSnSeed(int port); |
| | | void setPortCassetteSnSeed(int port, int seed); |
| | | CGlass* getGlass(int scrPort, int scrSlot); |
| | | uint32_t SlotToMid(int eqid, int slot); |
| | | |
| | | private: |
| | | inline void lock() { EnterCriticalSection(&m_criticalSection); } |
| | |
| | | bool carrierPresent(const std::string& carrierId) const override; |
| | | bool slotUsable(const std::string& carrierId, uint16_t slot) const override; |
| | | bool ceidDefined(uint32_t ceid) const override; |
| | | void setAllowedCeids(const std::vector<unsigned int>& ceids); |
| | | void handleCollectionEvent(uint32_t ceid); |
| | | bool raiseSoftAlarm(int alarmId, |
| | | const std::string& desc, |
| | | int level = -1, |
| | | int deviceId = 0, |
| | | int unitId = 0, |
| | | const char* deviceName = "Software", |
| | | const char* unitName = "App"); |
| | | |
| | | public: |
| | | int getLastError(); |
| | |
| | | bool canCompleteControlJob(); |
| | | bool canDeleteControlJob(); |
| | | |
| | | // DAQ Bridgeé©ç¨¿å§ |
| | | // DAQ Bridge ç¸å
³ |
| | | Collector* getCollector() const { return m_pCollector; } |
| | | |
| | | private: |
| | |
| | | ULONGLONG m_ullStartTime; |
| | | ULONGLONG m_ullRunTime; |
| | | MASTERSTATE m_state; |
| | | CurveMode m_curveMode; |
| | | |
| | | // å½åä»»å¡å已宿任å¡å表 |
| | | CRobotTask* m_pActiveRobotTask; |
| | |
| | | int m_nLastError; |
| | | std::string m_strLastError; |
| | | |
| | | // å¨å¼å§å·¥èºåæ¯å¦å
éè¦å
æ¯è¾map |
| | | // å¨å¼å§å·¥èºåæ¯å¦éè¦å
æ¯è¾ map |
| | | BOOL m_isCompareMapsBeforeProceeding; |
| | | BOOL m_bJobMode; |
| | | |
| | | |
| | | // åä¼ åæ°è®¡æ° |
| | | int m_nContinuousTransferCount; |
| | |
| | | int m_nContinuousWorkingPort; |
| | | int m_nContinuousWorkingSlot; |
| | | |
| | | // æ°å¢å·²ç»å¼å§å¤ççProcessJobå表 |
| | | // å·²ç»å¼å§å¤çç ProcessJob å表 |
| | | std::vector<CProcessJob*> m_inProcesJobs; |
| | | std::vector<CProcessJob*> m_completeProcessJobs; |
| | | std::vector<CGlass*> m_queueGlasses; |
| | |
| | | private: |
| | | bool m_bEnableEventReport; |
| | | bool m_bEnableAlarmReport; |
| | | bool m_bPauseAlarmRaised; |
| | | SERVO::CControlJob* m_pControlJob; |
| | | std::vector<SERVO::CProcessJob*> m_processJobs; |
| | | std::string m_strStatePath; |
| | | CModel* m_pModelCtx; |
| | | |
| | | int m_nTestFlag; |
| | | std::list<CGlass*> m_bufGlass; |
| | | std::unordered_set<uint32_t> m_allowedCeids; |
| | | |
| | | private: |
| | | Collector* m_pCollector = nullptr; |
| | | void CreateDAQBridgeServer(); |
| | | inline void notifyControlJobChanged() { |
| | | if (m_listener.onControlJobChanged) { |
| | | m_listener.onControlJobChanged(this); |
| | | } |
| | | } |
| | | }; |
| | | } |
| | | |
| | |
| | | SetDlgItemText(IDC_LABEL_RUNTIME, pszText); |
| | | } |
| | | |
| | | void CMyStatusbar::setJobText(const char* pszText) |
| | | { |
| | | SetDlgItemText(IDC_LABEL_JOBSTATE, pszText); |
| | | } |
| | | |
| | | void CMyStatusbar::setCurTaskBtnText(const char* pszText) |
| | | { |
| | | SetDlgItemText(IDC_BUTTON_ROBOTTASK, pszText); |
| | |
| | | void CMyStatusbar::setCimBtnText(const char* pszText) |
| | | { |
| | | 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() |
| | |
| | | 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(); |
| | | |
| | | x += 8; |
| | | pItem = GetDlgItem(IDC_LABEL_JOBSTATE); |
| | | if (pItem != nullptr) { |
| | | pItem->GetClientRect(rcItem); |
| | | pItem->MoveWindow(x, (rcClient.Height() - rcItem.Height()) / 2, rcItem.Width(), rcItem.Height()); |
| | | x += rcItem.Width(); |
| | | } |
| | | } |
| | |
| | | void setBackgroundColor(COLORREF color); |
| | | void setForegroundColor(COLORREF cr); |
| | | void setRunTimeText(const char* pszText); |
| | | void setJobText(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(); |
| | |
| | | #include "Servo.h" |
| | | #include "CPageCollectionEvent.h" |
| | | #include "afxdialogex.h" |
| | | #include "CEventEditDlg.h" |
| | | |
| | | |
| | | // CPageCollectionEvent å¯¹è¯æ¡ |
| | |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_DESTROY() |
| | | ON_WM_SIZE() |
| | | ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CPageCollectionEvent::OnLvnItemchangedList1) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | |
| | | m_listCtrl.SetItemText(index, 4, item->getReportIdsText().c_str()); |
| | | } |
| | | } |
| | | |
| | | void CPageCollectionEvent::OnCreateBtns() |
| | | { |
| | | const int BTN_W = 80; |
| | | const int BTN_H = 28; |
| | | CreateBtn(_T("æ°å¢"), BTN_W, BTN_H, 3001); |
| | | CreateBtn(_T("å é¤"), BTN_W, BTN_H, 3002)->EnableWindow(FALSE); |
| | | CreateBtn(_T("ç¼è¾"), BTN_W, BTN_H, 3003)->EnableWindow(FALSE); |
| | | } |
| | | |
| | | void CPageCollectionEvent::OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult) |
| | | { |
| | | LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); |
| | | int nSelCount = m_listCtrl.GetSelectedCount(); |
| | | if (CButton* pDel = GetBtnByName("å é¤")) { |
| | | pDel->EnableWindow(nSelCount > 0); |
| | | } |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) { |
| | | pEdit->EnableWindow(nSelCount > 0); |
| | | } |
| | | *pResult = 0; |
| | | } |
| | | |
| | | void CPageCollectionEvent::OnClickedBtn(const char* btnName) |
| | | { |
| | | ASSERT(btnName); |
| | | if (_strcmpi(btnName, "æ°å¢") == 0) { |
| | | int rc = UX_CanExecute(L"addEvents"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | unsigned int newId = theApp.m_model.m_hsmsPassive.getMaxCollectionEventId() + 1; |
| | | std::vector<unsigned int> rptIds; |
| | | CEventEditDlg dlg(_T("æ°å¢äºä»¶"), (int)newId, _T(""), _T(""), rptIds, this); |
| | | if (dlg.DoModal() != IDOK) return; |
| | | |
| | | int ret = theApp.m_model.m_hsmsPassive.addCollectionEvent(newId, CT2A(dlg.GetNameText()), CT2A(dlg.GetDescText()), dlg.GetSelectedRptIds()); |
| | | if (ret == 0) { |
| | | UX_RecordAction(L"addEvents"); |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadCollectionEvents(); |
| | | if (CButton* pDel = GetBtnByName("å é¤")) pDel->EnableWindow(FALSE); |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) pEdit->EnableWindow(FALSE); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("æ°å¢äºä»¶å¤±è´¥ï¼å¯è½IDé夿åå
¥å¤±è´¥ï¼")); |
| | | } |
| | | } |
| | | else if (_strcmpi(btnName, "å é¤") == 0) { |
| | | POSITION pos = m_listCtrl.GetFirstSelectedItemPosition(); |
| | | if (pos == nullptr) return; |
| | | int nItem = m_listCtrl.GetNextSelectedItem(pos); |
| | | auto pEvent = reinterpret_cast<SERVO::CCollectionEvent*>(m_listCtrl.GetItemData(nItem)); |
| | | if (pEvent == nullptr) return; |
| | | |
| | | int rc = UX_CanExecute(L"delEvents"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | |
| | | int ret = theApp.m_model.m_hsmsPassive.deleteCollectionEvent((unsigned short)pEvent->getEventId()); |
| | | if (ret == 0) { |
| | | UX_RecordAction(L"delEvents"); |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadCollectionEvents(); |
| | | if (CButton* pDel = GetBtnByName("å é¤")) pDel->EnableWindow(FALSE); |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) pEdit->EnableWindow(FALSE); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("å é¤äºä»¶å¤±è´¥")); |
| | | } |
| | | } |
| | | else if (_strcmpi(btnName, "ç¼è¾") == 0) { |
| | | POSITION pos = m_listCtrl.GetFirstSelectedItemPosition(); |
| | | if (pos == nullptr) return; |
| | | int nItem = m_listCtrl.GetNextSelectedItem(pos); |
| | | auto pEvent = reinterpret_cast<SERVO::CCollectionEvent*>(m_listCtrl.GetItemData(nItem)); |
| | | if (pEvent == nullptr) return; |
| | | |
| | | int rc = UX_CanExecute(L"editEvents"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | |
| | | CString name = pEvent->getName().c_str(); |
| | | CString desc = pEvent->getDescription().c_str(); |
| | | auto rptIds = pEvent->getReportIds(); |
| | | CEventEditDlg dlg(_T("ç¼è¾äºä»¶"), (int)pEvent->getEventId(), name, desc, rptIds, this); |
| | | if (dlg.DoModal() != IDOK) return; |
| | | |
| | | int ret = theApp.m_model.m_hsmsPassive.updateCollectionEvent(pEvent->getEventId(), CT2A(dlg.GetNameText()), CT2A(dlg.GetDescText()), dlg.GetSelectedRptIds()); |
| | | if (ret == 0) { |
| | | UX_RecordAction(L"editEvents"); |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadCollectionEvents(); |
| | | if (CButton* pDel = GetBtnByName("å é¤")) pDel->EnableWindow(FALSE); |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) pEdit->EnableWindow(FALSE); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("ç¼è¾äºä»¶å¤±è´¥ï¼å¯è½åå
¥å¤±è´¥ï¼")); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | private: |
| | | CListCtrlEx m_listCtrl; |
| | | void OnCreateBtns() override; |
| | | void OnClickedBtn(const char* btnName) override; |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | |
| | | 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 OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // CPageCtrlState.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "CPageCtrlState.h" |
| | | #include "afxdialogex.h" |
| | | #include "Common.h" |
| | | #include "Model.h" |
| | | #include "ColorTransfer.h" |
| | | |
| | | |
| | | // CPageCtrlState å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CPageCtrlState, CDialogEx) |
| | | |
| | | CPageCtrlState::CPageCtrlState(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_PROD_CTRL_STATE, pParent) |
| | | { |
| | | |
| | | } |
| | | |
| | | CPageCtrlState::~CPageCtrlState() |
| | | { |
| | | } |
| | | |
| | | void CPageCtrlState::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_BUTTON_OFFLINE, m_btnOffline); |
| | | DDX_Control(pDX, IDC_BUTTON_ONLINE_LOCAL, m_btnOnlineLocal); |
| | | DDX_Control(pDX, IDC_BUTTON_ONLINE_REMOTE, m_btnOnlineRemote); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CPageCtrlState, CDialogEx) |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_SIZE() |
| | | ON_WM_DESTROY() |
| | | ON_BN_CLICKED(IDC_BUTTON_OFFLINE, &CPageCtrlState::OnBnClickedOffline) |
| | | ON_BN_CLICKED(IDC_BUTTON_ONLINE_LOCAL, &CPageCtrlState::OnBnClickedOnlineLocal) |
| | | ON_BN_CLICKED(IDC_BUTTON_ONLINE_REMOTE, &CPageCtrlState::OnBnClickedOnlineRemote) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CPageCtrlState æ¶æ¯å¤çç¨åº |
| | | |
| | | void CPageCtrlState::InitRxWindows() |
| | | { |
| | | IRxWindows* pRxWindows = RX_GetRxWindows(); |
| | | if (m_pObserver == nullptr) { |
| | | m_pObserver = pRxWindows->allocObserver([this](IAny* pAny) -> void { |
| | | pAny->addRef(); |
| | | const int code = pAny->getCode(); |
| | | if (code == RX_CODE_CONTROL_STATE_CHANGED && ::IsWindow(m_hWnd)) { |
| | | UpdateButtonStyles(); |
| | | } |
| | | pAny->release(); |
| | | }, [&]() -> void { |
| | | // onComplete |
| | | }, [&](IThrowable* pThrowable) -> void { |
| | | // onError |
| | | pThrowable->printf(); |
| | | }); |
| | | |
| | | theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread()) |
| | | ->subscribe(m_pObserver); |
| | | } |
| | | } |
| | | |
| | | void CPageCtrlState::ApplyButtonTheme(CBlButton& btn, bool active) |
| | | { |
| | | const COLORREF text = active ? RGB(255, 255, 255) : RGB(0, 0, 0); |
| | | const COLORREF normal = active ? RGB(34, 177, 76) : RGB(222, 222, 222); |
| | | const COLORREF hover = CColorTransfer::ApproximateColor(normal, active ? 0.08 : 0.05); |
| | | const COLORREF press = CColorTransfer::ApproximateColor(normal, active ? -0.10 : -0.12); |
| | | const COLORREF frame = active ? CColorTransfer::ApproximateColor(normal, -0.18) : RGB(168, 168, 168); |
| | | |
| | | btn.SetRoundWidth(6); |
| | | btn.SetTextColor(BS_NORMAL, text); |
| | | btn.SetTextColor(BS_HOVER, text); |
| | | btn.SetTextColor(BS_PRESS, text); |
| | | btn.SetTextColor(BS_DISABLE, RGB(120, 120, 120)); |
| | | |
| | | btn.SetBkgndColor(BS_NORMAL, normal); |
| | | btn.SetBkgndColor(BS_HOVER, hover); |
| | | btn.SetBkgndColor(BS_PRESS, press); |
| | | btn.SetBkgndColor(BS_DISABLE, RGB(210, 210, 210)); |
| | | |
| | | btn.SetFrameColor(BS_NORMAL, frame); |
| | | btn.SetFrameColor(BS_HOVER, frame); |
| | | btn.SetFrameColor(BS_PRESS, frame); |
| | | btn.SetFrameColor(BS_DISABLE, RGB(180, 180, 180)); |
| | | } |
| | | |
| | | void CPageCtrlState::UpdateButtonStyles() |
| | | { |
| | | const auto state = theApp.m_model.getControlState(); |
| | | ApplyButtonTheme(m_btnOffline, state == ControlState::OfflineEquipment || state == ControlState::OfflineHost); |
| | | ApplyButtonTheme(m_btnOnlineLocal, state == ControlState::OnlineLocal); |
| | | ApplyButtonTheme(m_btnOnlineRemote, state == ControlState::OnlineRemote); |
| | | |
| | | Invalidate(); |
| | | UpdateWindow(); |
| | | } |
| | | |
| | | BOOL CPageCtrlState::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | // TODO: 卿¤æ·»å é¢å¤çåå§å |
| | | InitRxWindows(); |
| | | UpdateButtonStyles(); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | | |
| | | |
| | | HBRUSH CPageCtrlState::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) |
| | | { |
| | | HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); |
| | | |
| | | // TODO: 卿¤æ´æ¹ DC çä»»ä½ç¹æ§ |
| | | |
| | | // TODO: 妿é»è®¤ç䏿¯æéç»ç¬ï¼åè¿åå¦ä¸ä¸ªç»ç¬ |
| | | return hbr; |
| | | } |
| | | |
| | | void CPageCtrlState::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | |
| | | // TODO: 卿¤å¤æ·»å æ¶æ¯å¤çç¨åºä»£ç |
| | | } |
| | | |
| | | void CPageCtrlState::OnDestroy() |
| | | { |
| | | CDialogEx::OnDestroy(); |
| | | |
| | | // TODO: 卿¤å¤æ·»å æ¶æ¯å¤çç¨åºä»£ç |
| | | } |
| | | |
| | | void CPageCtrlState::OnBnClickedOffline() |
| | | { |
| | | theApp.m_model.setControlState(ControlState::OfflineEquipment); |
| | | } |
| | | |
| | | void CPageCtrlState::OnBnClickedOnlineLocal() |
| | | { |
| | | theApp.m_model.setControlState(ControlState::OnlineLocal); |
| | | } |
| | | |
| | | void CPageCtrlState::OnBnClickedOnlineRemote() |
| | | { |
| | | theApp.m_model.setControlState(ControlState::OnlineRemote); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "BlButton.h" |
| | | |
| | | // CPageCtrlState å¯¹è¯æ¡ |
| | | |
| | | class CPageCtrlState : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CPageCtrlState) |
| | | |
| | | public: |
| | | CPageCtrlState(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CPageCtrlState(); |
| | | |
| | | private: |
| | | void InitRxWindows(); |
| | | void UpdateButtonStyles(); |
| | | void ApplyButtonTheme(CBlButton& btn, bool active); |
| | | |
| | | CBlButton m_btnOffline; |
| | | CBlButton m_btnOnlineLocal; |
| | | CBlButton m_btnOnlineRemote; |
| | | IObserver* m_pObserver{ nullptr }; |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_PROD_CTRL_STATE }; |
| | | #endif |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnDestroy(); |
| | | afx_msg void OnBnClickedOffline(); |
| | | afx_msg void OnBnClickedOnlineLocal(); |
| | | afx_msg void OnBnClickedOnlineRemote(); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // CPageDataVarialbles.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "CPageDataVarialbles.h" |
| | | #include "afxdialogex.h" |
| | | #include "CVariableEditDlg2.h" |
| | | |
| | | IMPLEMENT_DYNAMIC(CPageDataVarialbles, CHMPropertyPage) |
| | | |
| | | CPageDataVarialbles::CPageDataVarialbles(CWnd* pParent /*=nullptr*/) |
| | | : CHMPropertyPage(IDD_PAGE_VARIABLE, pParent) |
| | | { |
| | | } |
| | | |
| | | CPageDataVarialbles::~CPageDataVarialbles() |
| | | { |
| | | } |
| | | |
| | | void CPageDataVarialbles::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CHMPropertyPage::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_LIST1, m_listCtrl); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CPageDataVarialbles, CHMPropertyPage) |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_DESTROY() |
| | | ON_WM_SIZE() |
| | | ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CPageDataVarialbles::OnLvnItemchangedList1) |
| | | END_MESSAGE_MAP() |
| | | |
| | | BOOL CPageDataVarialbles::OnInitDialog() |
| | | { |
| | | CHMPropertyPage::OnInitDialog(); |
| | | |
| | | // 读åºå宽ï¼ç¬ç«ç ini åèï¼é¿å
ä¸ SVID 页é¢å²çªï¼ |
| | | CString strIniFile, strItem; |
| | | strIniFile.Format(_T("%s\\configuration.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | int width[8] = { 0, 218, 180, 180, 180, 180, 180, 180 }; |
| | | for (int i = 0; i < 8; i++) { |
| | | strItem.Format(_T("Col_%d_Width"), i); |
| | | width[i] = GetPrivateProfileInt("PageDataVariableListCtrl", strItem, width[i], strIniFile); |
| | | } |
| | | |
| | | DWORD dwStyle = m_listCtrl.GetExtendedStyle(); |
| | | dwStyle |= LVS_EX_FULLROWSELECT; |
| | | dwStyle |= LVS_EX_GRIDLINES; |
| | | m_listCtrl.SetExtendedStyle(dwStyle); |
| | | |
| | | HIMAGELIST imageList = ImageList_Create(24, 24, ILC_COLOR24, 1, 1); |
| | | ListView_SetImageList(m_listCtrl.GetSafeHwnd(), imageList, LVSIL_SMALL); |
| | | m_listCtrl.InsertColumn(0, _T(""), LVCFMT_RIGHT, width[0]); |
| | | m_listCtrl.InsertColumn(1, _T("DV ID"), LVCFMT_LEFT, width[1]); |
| | | m_listCtrl.InsertColumn(2, _T("DV Name"), LVCFMT_LEFT, width[2]); |
| | | m_listCtrl.InsertColumn(3, _T("DV Format"), LVCFMT_LEFT, width[3]); |
| | | m_listCtrl.InsertColumn(4, _T("DV Remark"), LVCFMT_LEFT, width[4]); |
| | | |
| | | loadDataVariables(); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | HBRUSH CPageDataVarialbles::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) |
| | | { |
| | | return CHMPropertyPage::OnCtlColor(pDC, pWnd, nCtlColor); |
| | | } |
| | | |
| | | void CPageDataVarialbles::OnDestroy() |
| | | { |
| | | CHMPropertyPage::OnDestroy(); |
| | | |
| | | // ä¿åå宽 |
| | | CString strIniFile, strItem, strTemp; |
| | | strIniFile.Format(_T("%s\\configuration.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | CHeaderCtrl* pHeader = m_listCtrl.GetHeaderCtrl(); |
| | | for (int i = 0; i < pHeader->GetItemCount(); i++) { |
| | | RECT rect; |
| | | pHeader->GetItemRect(i, &rect); |
| | | strItem.Format(_T("Col_%d_Width"), i); |
| | | strTemp.Format(_T("%d"), rect.right - rect.left); |
| | | WritePrivateProfileString("PageDataVariableListCtrl", strItem, strTemp, strIniFile); |
| | | } |
| | | } |
| | | |
| | | void CPageDataVarialbles::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CHMPropertyPage::OnSize(nType, cx, cy); |
| | | if (GetDlgItem(IDC_LIST1) == nullptr) return; |
| | | |
| | | CRect rcClient; |
| | | GetClientRect(&rcClient); |
| | | m_listCtrl.MoveWindow(12, 12, rcClient.Width() - 24, rcClient.Height() - 24); |
| | | } |
| | | |
| | | void CPageDataVarialbles::OnApply() |
| | | { |
| | | __super::OnApply(); |
| | | } |
| | | |
| | | void CPageDataVarialbles::loadDataVariables() |
| | | { |
| | | auto& dvars = theApp.m_model.m_hsmsPassive.getDataVariables(); |
| | | for (auto item : dvars) { |
| | | int index = m_listCtrl.InsertItem(m_listCtrl.GetItemCount(), _T("")); |
| | | m_listCtrl.SetItemData(index, (DWORD_PTR)item); |
| | | m_listCtrl.SetItemText(index, 1, std::to_string(item->getVarialbleId()).c_str()); |
| | | m_listCtrl.SetItemText(index, 2, item->getName().c_str()); |
| | | m_listCtrl.SetItemText(index, 3, SERVO::CVariable::formatToString(item->getFormat()).c_str()); |
| | | m_listCtrl.SetItemText(index, 4, item->getRemark().c_str()); |
| | | } |
| | | } |
| | | |
| | | void CPageDataVarialbles::OnCreateBtns() |
| | | { |
| | | const int BTN_W = 80; |
| | | const int BTN_H = 28; |
| | | CreateBtn(_T("æ°å¢"), BTN_W, BTN_H, 1001); |
| | | CreateBtn(_T("å é¤"), BTN_W, BTN_H, 1002)->EnableWindow(FALSE); |
| | | CreateBtn(_T("ç¼è¾"), BTN_W, BTN_H, 1003)->EnableWindow(FALSE); |
| | | } |
| | | |
| | | void CPageDataVarialbles::OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult) |
| | | { |
| | | LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); |
| | | int nSelCount = m_listCtrl.GetSelectedCount(); |
| | | |
| | | if (CButton* pDel = GetBtnByName("å é¤")) { |
| | | pDel->EnableWindow(nSelCount > 0); |
| | | } |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) { |
| | | pEdit->EnableWindow(nSelCount > 0); |
| | | } |
| | | |
| | | *pResult = 0; |
| | | } |
| | | |
| | | void CPageDataVarialbles::OnClickedBtn(const char* btnName) |
| | | { |
| | | ASSERT(btnName); |
| | | if (_strcmpi(btnName, "æ°å¢") == 0) { |
| | | int rc = UX_CanExecute(L"addVarialbles"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | unsigned int newId = theApp.m_model.m_hsmsPassive.getMaxDataVariableId(); |
| | | int newIdInt = static_cast<int>(newId + 1); |
| | | CVariableEditDlg2 dlg(_T("æ°å¢æ°æ®åé"), newIdInt, _T("U1"), _T(""), _T(""), this); |
| | | if (dlg.DoModal() != IDOK) return; |
| | | CString name = dlg.GetNameText(); |
| | | CString fmt = dlg.GetTypeText(); |
| | | CString remark = dlg.GetRemark(); |
| | | |
| | | int ret = theApp.m_model.m_hsmsPassive.addDataVariable(CT2A(name), CT2A(fmt), CT2A(remark), newIdInt); |
| | | if (ret == 0) { |
| | | UX_RecordAction(L"addVarialbles"); |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadDataVariables(); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("æ°å¢æ°æ®åéå¤±è´¥ï¼æ ¼å¼æ¯å¦æ£ç¡®ï¼(U1/U2/I2/A20/A50/L)")); |
| | | } |
| | | } |
| | | else if (_strcmpi(btnName, "å é¤") == 0) { |
| | | POSITION pos = m_listCtrl.GetFirstSelectedItemPosition(); |
| | | if (pos == nullptr) return; |
| | | int nItem = m_listCtrl.GetNextSelectedItem(pos); |
| | | auto pVar = reinterpret_cast<SERVO::CDataVariable*>(m_listCtrl.GetItemData(nItem)); |
| | | if (pVar == nullptr) return; |
| | | |
| | | int rc = UX_CanExecute(L"delVarialbles"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | int ret = theApp.m_model.m_hsmsPassive.deleteDataVariable(static_cast<int>(pVar->getVarialbleId())); |
| | | if (ret == 0) { |
| | | UX_RecordAction(L"delVarialbles"); |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadDataVariables(); |
| | | if (CButton* pDel = GetBtnByName("å é¤")) pDel->EnableWindow(FALSE); |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) pEdit->EnableWindow(FALSE); |
| | | } |
| | | } |
| | | else if (_strcmpi(btnName, "ç¼è¾") == 0) { |
| | | POSITION pos = m_listCtrl.GetFirstSelectedItemPosition(); |
| | | if (pos == nullptr) return; |
| | | int nItem = m_listCtrl.GetNextSelectedItem(pos); |
| | | auto pVar = reinterpret_cast<SERVO::CDataVariable*>(m_listCtrl.GetItemData(nItem)); |
| | | if (pVar == nullptr) return; |
| | | |
| | | int rc = UX_CanExecute(L"editVarialbles"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | CVariableEditDlg2 dlg(_T("ç¼è¾æ°æ®åé"), |
| | | pVar->getVarialbleId(), |
| | | CString(CA2T(SERVO::CVariable::formatToString(pVar->getFormat()).c_str())), |
| | | CString(CA2T(pVar->getName().c_str())), |
| | | CString(CA2T(pVar->getRemark().c_str())), |
| | | this); |
| | | if (dlg.DoModal() != IDOK) return; |
| | | CString name = dlg.GetNameText(); |
| | | CString fmt = dlg.GetTypeText(); |
| | | CString remark = dlg.GetRemark(); |
| | | |
| | | int ret = theApp.m_model.m_hsmsPassive.updateDataVariable(static_cast<int>(pVar->getVarialbleId()), CT2A(name), CT2A(fmt), CT2A(remark)); |
| | | if (ret == 0) { |
| | | UX_RecordAction(L"editVarialbles"); |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadDataVariables(); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("ç¼è¾æ°æ®åéå¤±è´¥ï¼æ ¼å¼æ¯å¦æ£ç¡®ï¼(U1/U2/I2/A20/A50/L)")); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "CHMPropertyPage.h" |
| | | #include "ListCtrlEx.h" |
| | | |
| | | // CPageDataVarialbles å¯¹è¯æ¡ï¼DVID ç¼è¾/æ¥çï¼ |
| | | class CPageDataVarialbles : public CHMPropertyPage |
| | | { |
| | | DECLARE_DYNAMIC(CPageDataVarialbles) |
| | | |
| | | public: |
| | | CPageDataVarialbles(CWnd* pParent = nullptr); |
| | | virtual ~CPageDataVarialbles(); |
| | | virtual void OnApply(); |
| | | void loadDataVariables(); |
| | | virtual void OnCreateBtns(); |
| | | |
| | | private: |
| | | CListCtrlEx m_listCtrl; |
| | | |
| | | protected: |
| | | virtual void OnClickedBtn(const char* btnName) override; |
| | | |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_PAGE_VARIABLE }; |
| | | #endif |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); |
| | | |
| | | 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 OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult); |
| | | }; |
| | |
| | | #include <unordered_map> |
| | | #include <vector> |
| | | #include <string> |
| | | #include <algorithm> |
| | | #include "CProcessDataListDlg.h" |
| | | |
| | | #define PAGE_SIZE 50 |
| | |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | // 宿¶å¨ï¼1=åå§å订é
ï¼2=卿巿°ï¼åªå¢éï¼ |
| | | // 宿¶å¨ï¼1=åå§å订é
ï¼2=卿巿°ï¼åªå¢éï¼ï¼3=å»¶è¿å è½½é¦å±æ°æ® |
| | | SetTimer(1, 3000, nullptr); |
| | | SetTimer(2, 2000, nullptr); |
| | | SetTimer(3, 10, nullptr); |
| | | |
| | | // ä¸ææ¡æ§ä»¶ |
| | | InitStatusCombo(); |
| | |
| | | m_listCtrl.SetPopupFullTextColumns({ 11, 12 }); |
| | | |
| | | Resize(); |
| | | OnBnClickedButtonSearch(); // 触å䏿¬¡æ¥è¯¢ä¸é¦å±å¡«å
|
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | } |
| | |
| | | else if (nIDEvent == 2) { |
| | | UpdateWipData(); // åªåå¢éï¼ä¸é建 |
| | | } |
| | | else if (nIDEvent == 3) { |
| | | KillTimer(3); |
| | | OnBnClickedButtonSearch(); // å»¶è¿é¦å±æ¥è¯¢ï¼é¿å
å¡ä½ OnInitDialog |
| | | } |
| | | |
| | | CDialogEx::OnTimer(nIDEvent); |
| | | } |
| | |
| | | |
| | | void CPageGlassList::OnBnClickedButtonSearch() |
| | | { |
| | | CWaitCursor wait; // æ¾ç¤ºçå¾
å
æ ï¼æç¤ºæ£å¨å è½½ |
| | | |
| | | // è·åå
³é®åè¾å
¥æ¡å
容 |
| | | CString strKeyword; |
| | | GetDlgItemText(IDC_EDIT_KEYWORD, strKeyword); |
| | |
| | | if (!row.pretty.empty()) { |
| | | CFile file; |
| | | if (file.Open(filePath, CFile::modeCreate | CFile::modeWrite)) { |
| | | file.Write(row.pretty.c_str(), row.pretty.length()); |
| | | file.Write(row.pretty.c_str(), (UINT)row.pretty.length()); |
| | | file.Close(); |
| | | |
| | | CString strSuccess; |
| | |
| | | // 对æ¯ä¸ªæºå¨çæè¡¨æ ¼ |
| | | for (const auto& machinePair : tempGlass.getAllSVData()) { |
| | | int machineId = machinePair.first; |
| | | const auto& dataByType = machinePair.second; |
| | | CString machineName = CString(SERVO::CServoUtilsTool::getEqName(machineId).c_str()); |
| | | |
| | | csvContent += _T("\n[") + machineName + _T("]\n"); |
| | | |
| | | // è·å该æºå¨çé¢å®ä¹åé¡ºåº |
| | | auto columnOrder = getMachineColumnOrder(machineId); |
| | | |
| | | if (columnOrder.empty()) { |
| | | csvContent += _T("æ é¢å®ä¹åé
ç½®\n"); |
| | | if (dataByType.empty()) { |
| | | csvContent += _T("No sensor data\n"); |
| | | continue; |
| | | } |
| | | |
| | | // æå»ºè¡¨å¤´ - ç´æ¥ä½¿ç¨ä¸æåå |
| | | CString header = _T("æ¶é´æ³(ms),æ¬å°æ¶é´"); |
| | | auto columnOrder = getMachineColumnOrder(machineId, &dataByType); |
| | | if (columnOrder.empty()) { |
| | | csvContent += _T("No exportable columns\n"); |
| | | continue; |
| | | } |
| | | |
| | | CString header = _T("Timestamp(ms),LocalTime"); |
| | | for (const auto& dataType : columnOrder) { |
| | | header += _T(","); |
| | | header += CString(dataType.c_str()); // ç´æ¥ä½¿ç¨ä¸æåå |
| | | header += CString(dataType.c_str()); |
| | | } |
| | | header += _T("\n"); |
| | | csvContent += header; |
| | | |
| | | // æ£æ¥æ¯å¦ææ°æ® |
| | | if (machinePair.second.empty()) { |
| | | csvContent += _T("æ ä¼ æå¨æ°æ®\n"); |
| | | auto baselineIt = std::find_if(columnOrder.begin(), columnOrder.end(), |
| | | [&](const std::string& type) { |
| | | auto dataIt = dataByType.find(type); |
| | | return dataIt != dataByType.end() && !dataIt->second.empty(); |
| | | }); |
| | | if (baselineIt == columnOrder.end()) { |
| | | csvContent += _T("No usable time series\n"); |
| | | continue; |
| | | } |
| | | |
| | | // 使ç¨ç¬¬ä¸ä¸ªæ°æ®ç±»åçæ¶é´åºåä½ä¸ºåºå |
| | | const std::string& firstDataType = columnOrder[0]; |
| | | auto firstDataTypeIt = machinePair.second.find(firstDataType); |
| | | if (firstDataTypeIt == machinePair.second.end() || firstDataTypeIt->second.empty()) { |
| | | csvContent += _T("æ åºåæ°æ®ç±»åæ°æ®\n"); |
| | | continue; |
| | | } |
| | | |
| | | const auto& timeSeries = firstDataTypeIt->second; |
| | | |
| | | // å¯¹äºæ¯ä¸ªæ¶é´ç¹ï¼è¾åºä¸è¡æ°æ® |
| | | for (size_t i = 0; i < timeSeries.size(); i++) { |
| | | const auto& timeSeries = dataByType.at(*baselineIt); |
| | | for (size_t i = 0; i < timeSeries.size(); ++i) { |
| | | auto timestamp = timeSeries[i].timestamp; |
| | | |
| | | // æ¶é´æ³ï¼æ¯«ç§ï¼ |
| | | auto ms = timePointToMs(timestamp); |
| | | CString row; |
| | | row.Format(_T("%lld,"), ms); |
| | | |
| | | // æ¬å°æ¶é´å符串 |
| | | CString localTime = CString(timePointToString(timestamp).c_str()); |
| | | row += localTime; |
| | | |
| | | // æç
§é¢å®ä¹çå顺åºè¾åºæ°æ® |
| | | for (const auto& dataType : columnOrder) { |
| | | row += _T(","); |
| | | |
| | | auto dataTypeIt = machinePair.second.find(dataType); |
| | | if (dataTypeIt != machinePair.second.end() && i < dataTypeIt->second.size()) { |
| | | // ç´æ¥æç´¢å¼è·åæ°æ® |
| | | auto dataTypeIt = dataByType.find(dataType); |
| | | if (dataTypeIt != dataByType.end() && i < dataTypeIt->second.size()) { |
| | | CString valueStr; |
| | | valueStr.Format(_T("%.3f"), dataTypeIt->second[i].value); |
| | | row += valueStr; |
| | | } |
| | | else { |
| | | // ç论ä¸ä¸åºè¯¥åçï¼å 为æ¨è¯´æ²¡æç©ºå¼ |
| | | row += _T("N/A"); |
| | | } |
| | | } |
| | |
| | | auto* p = reinterpret_cast<NMC_ELC_SHOWFULLTEXT*>(pNMHDR); |
| | | |
| | | // å¯¹è¯æ¡æ¾ç¤ºå·¥èºåæ° |
| | | if (p->iSubItem == 12) { |
| | | CProcessDataListDlg dlg; |
| | | dlg.setRawText(p->text); |
| | | dlg.DoModal(); |
| | | } |
| | | else { |
| | | AfxMessageBox(p->text); |
| | | } |
| | | |
| | | *pResult = 0; |
| | | } |
| | |
| | | } |
| | | |
| | | // è·åæºå¨é¢å®ä¹çåé¡ºåº |
| | | std::vector<std::string> CPageGlassList::getMachineColumnOrder(int machineId) |
| | | std::vector<std::string> CPageGlassList::getMachineColumnOrder(int machineId, |
| | | const std::unordered_map<std::string, std::vector<SERVO::SVDataItem>>* actualData) |
| | | { |
| | | std::vector<std::string> columnOrder; |
| | | auto dataTypes = SERVO::CServoUtilsTool::getEqDataTypes(); |
| | | auto it = dataTypes.find(machineId); |
| | | return it != dataTypes.end() ? it->second : std::vector<std::string>(); |
| | | |
| | | if (actualData != nullptr) { |
| | | if (it != dataTypes.end()) { |
| | | for (const auto& name : it->second) { |
| | | if (actualData->find(name) != actualData->end()) { |
| | | columnOrder.push_back(name); |
| | | } |
| | | } |
| | | } |
| | | for (const auto& kv : *actualData) { |
| | | if (std::find(columnOrder.begin(), columnOrder.end(), kv.first) == columnOrder.end()) { |
| | | columnOrder.push_back(kv.first); |
| | | } |
| | | } |
| | | return columnOrder; |
| | | } |
| | | |
| | | if (it != dataTypes.end()) { |
| | | columnOrder = it->second; |
| | | } |
| | | return columnOrder; |
| | | } |
| | | |
| | | // æ¶é´æ³è½¬æ¢ä¸ºå符串 |
| | |
| | | for (const auto& machinePair : dataTypes) { |
| | | int machineId = machinePair.first; |
| | | const auto& dataTypeList = machinePair.second; |
| | | std::vector<std::string> filteredTypes; |
| | | |
| | | if (machineId == EQ_ID_VACUUMBAKE || machineId == EQ_ID_BAKE_COOLING) { |
| | | const char activePrefix = 'A'; |
| | | for (const auto& dataType : dataTypeList) { |
| | | if (!dataType.empty() && dataType[0] == activePrefix) { |
| | | filteredTypes.push_back(dataType); |
| | | } |
| | | } |
| | | } |
| | | |
| | | const auto& typeList = filteredTypes.empty() ? dataTypeList : filteredTypes; |
| | | |
| | | // çææ¶é´åºåï¼ä»å½åæ¶é´å¾åæ¨10åéï¼æ¯1ç§ä¸ä¸ªæ°æ®ç¹ |
| | | auto now = std::chrono::system_clock::now(); |
| | | auto startTime = now - std::chrono::minutes(10); |
| | | |
| | | // 为æ¯ä¸ªæ°æ®ç±»åçææ¨¡ææ°æ® |
| | | for (const auto& dataType : dataTypeList) { |
| | | for (const auto& dataType : typeList) { |
| | | std::vector<SERVO::SVDataItem> mockData; |
| | | |
| | | // çæ600ä¸ªæ°æ®ç¹ï¼10åé * 60个ç¹/åéï¼ |
| | |
| | | #pragma once |
| | | #include "CExpandableListCtrl.h" |
| | | #include "GlassLogDb.h" |
| | | #include <unordered_map> |
| | | |
| | | // ====== ç¼è¯å¼å
³è¯´æ ====== |
| | | // USE_MOCK_SENSOR_DATA: 1=å¯ç¨æ¨¡æä¼ æå¨æ°æ®çæï¼0=使ç¨ç宿°æ® |
| | |
| | | void ExportBasicInfo(CString& csvContent, const GlassLogDb::Row& row); |
| | | void ExportProcessParams(CString& csvContent, const GlassLogDb::Row& row); |
| | | void ExportSensorData(CString& csvContent, const GlassLogDb::Row& row); |
| | | static std::vector<std::string> getMachineColumnOrder(int machineId); |
| | | static std::vector<std::string> getMachineColumnOrder(int machineId, const std::unordered_map<std::string, std::vector<SERVO::SVDataItem>>* actualData = nullptr); |
| | | static std::string timePointToString(const std::chrono::system_clock::time_point& tp); |
| | | static int64_t timePointToMs(const std::chrono::system_clock::time_point& tp); |
| | | void GenerateMockSVData(SERVO::CGlass& glass); |
| | |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | InitRxWindows(); |
| | | SetTimer(TIMER_ID_DEVICE_STATUS, 3000, nullptr); |
| | | SetTimer(TIMER_ID_DEVICE_STATUS, 800, nullptr); |
| | | SetTimer(TIMER_ID_ROBOT_STATUS, 1000, nullptr); // æ¯ 1000ms æ´æ°ä¸æ¬¡ç¶æ |
| | | |
| | | // å¾ç¤º |
| | |
| | | // Bonder |
| | | m_pGraph->AddIndicateBox(INDICATE_BONDER1, 220, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_BONDER1, "10", "Bonder 1"); |
| | | m_pGraph->SetBoxText(INDICATE_BONDER1, "", "Bonder 1"); |
| | | m_pGraph->AddIndicateBox(INDICATE_BONDER2, 220, 516, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_BONDER2, "11", "Bonder 2"); |
| | | m_pGraph->SetBoxText(INDICATE_BONDER2, "", "Bonder 2"); |
| | | |
| | | |
| | | // 翻转 |
| | | m_pGraph->AddIndicateBox(INDICATE_FLIPER, 338, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_FLIPER, "8", "Fliper"); |
| | | m_pGraph->SetBoxText(INDICATE_FLIPER, "", "Fliper"); |
| | | |
| | | |
| | | // å¯¹ä½ |
| | | m_pGraph->AddIndicateBox(INDICATE_ALIGNER, 428, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_ALIGNER, "7", "Aligner"); |
| | | m_pGraph->SetBoxText(INDICATE_ALIGNER, "", "Aligner"); |
| | | |
| | | |
| | | // Load port 4 |
| | | m_pGraph->AddIndicateBox(INDICATE_LPORT4, 518, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT4, "4", "LPort4"); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT4, "", "LPort4"); |
| | | |
| | | |
| | | // Load port 3 |
| | | m_pGraph->AddIndicateBox(INDICATE_LPORT3, 606, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT3, "3", "LPort3"); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT3, "", "LPort3"); |
| | | |
| | | |
| | | // Load port 2 |
| | | m_pGraph->AddIndicateBox(INDICATE_LPORT2, 690, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT2, "2", "LPort2"); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT2, "", "LPort2"); |
| | | |
| | | |
| | | // Load port 1 |
| | | m_pGraph->AddIndicateBox(INDICATE_LPORT1, 774, 172, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT1, "1", "LPort1"); |
| | | m_pGraph->SetBoxText(INDICATE_LPORT1, "", "LPort1"); |
| | | |
| | | |
| | | // Robot |
| | | m_pGraph->AddIndicateBox(INDICATE_ROBOT_ARM1, 190, 294, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_ROBOT_ARM1, "5", "Robot"); |
| | | m_pGraph->SetBoxText(INDICATE_ROBOT_ARM1, "", "Robot"); |
| | | m_pGraph->AddIndicateBox(INDICATE_ROBOT_ARM2, 243, 294, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_ROBOT_ARM2, "6", "Robot"); |
| | | m_pGraph->SetBoxText(INDICATE_ROBOT_ARM2, "", "Robot"); |
| | | |
| | | |
| | | // Vacuum bake |
| | | m_pGraph->AddIndicateBox(INDICATE_VACUUM_BAKE, 396, 516, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_VACUUM_BAKE, "9", "Vacuum bake"); |
| | | m_pGraph->SetBoxText(INDICATE_VACUUM_BAKE, "", "Vacuum bake"); |
| | | |
| | | |
| | | // Bake cooling |
| | | m_pGraph->AddIndicateBox(INDICATE_BAKE_COOLING, 566, 516, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_BAKE_COOLING, "12", "Bake cooling"); |
| | | m_pGraph->SetBoxText(INDICATE_BAKE_COOLING, "", "Bake cooling"); |
| | | |
| | | |
| | | // ç²¾åº¦æ£ |
| | | m_pGraph->AddIndicateBox(INDICATE_MEASUREMENT, 737, 516, 48, RGB(22, 22, 22), |
| | | RGB(255, 127, 39), EQ_BOX_OFFLINE); |
| | | m_pGraph->SetBoxText(INDICATE_MEASUREMENT, "13", "Measurement"); |
| | | m_pGraph->SetBoxText(INDICATE_MEASUREMENT, "", "Measurement"); |
| | | |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | |
| | | |
| | | // ç§»å¨å°æå®ä½ç½® (æµè¯ä½¿ç¨) |
| | | if (pGraphNmhdr->dwData == INDICATE_LPORT1) { |
| | | StartRobotMoveToPosition(SERVO::ROBOT_POSITION::Port1); |
| | | } |
| | | else if (pGraphNmhdr->dwData == INDICATE_LPORT2) { |
| | | StartRobotMoveToPosition(SERVO::ROBOT_POSITION::Port2); |
| | | } |
| | | else if (pGraphNmhdr->dwData == INDICATE_LPORT3) { |
| | | StartRobotMoveToPosition(SERVO::ROBOT_POSITION::Port3); |
| | | } |
| | | else if (pGraphNmhdr->dwData == INDICATE_LPORT4) { |
| | | StartRobotMoveToPosition(SERVO::ROBOT_POSITION::Port4); |
| | | } |
| | | else if (pGraphNmhdr->dwData == INDICATE_ALIGNER) { |
| | | StartRobotMoveToPosition(SERVO::ROBOT_POSITION::Aligner); |
| | | } |
| | | else if (pGraphNmhdr->dwData == INDICATE_FLIPER) { |
| | | StartRobotMoveToPosition(SERVO::ROBOT_POSITION::Fliper); |
| | | } |
| | | else if (pGraphNmhdr->dwData == INDICATE_BONDER1) { |
| | | StartRobotMoveToPosition(SERVO::ROBOT_POSITION::Bonder1); |
| | | } |
| | | else if (pGraphNmhdr->dwData == INDICATE_BONDER2) { |
| | | StartRobotMoveToPosition(SERVO::ROBOT_POSITION::Bonder2); |
| | | } |
| | | else if (pGraphNmhdr->dwData == INDICATE_VACUUM_BAKE) { |
| | | StartRobotMoveToPosition(SERVO::ROBOT_POSITION::Bake); |
| | | } |
| | | else if (pGraphNmhdr->dwData == INDICATE_BAKE_COOLING) { |
| | | StartRobotMoveToPosition(SERVO::ROBOT_POSITION::Cooling); |
| | | } |
| | | else if (pGraphNmhdr->dwData == INDICATE_MEASUREMENT) { |
| | | StartRobotMoveToPosition(SERVO::ROBOT_POSITION::Measurement); |
| | | |
| | | } |
| | | |
| | | *pResult = 0; |
| | |
| | | if (RX_CODE_EQ_DATA_CHANGED == code) { |
| | | // éç¥è®¾å¤ç¶æ |
| | | SERVO::CEquipment* pEquipment = nullptr; |
| | | if (pAny->getPtrValue("ptr", (void*&)pEquipment)) { |
| | | if (pEquipment != nullptr) { |
| | | m_pEqsGraphWnd->ShowItemIndicator((DWORD_PTR)pEquipment, pEquipment->hasGlass()); |
| | | } |
| | | if (pAny->getPtrValue("ptr", (void*&)pEquipment) && pEquipment != nullptr) { |
| | | UpdateItemIndicators(pEquipment); |
| | | } |
| | | } |
| | | |
| | |
| | | m_pEqsGraphWnd->SetBkgndColor(m_crBkgnd); |
| | | m_pEqsGraphWnd->SetOnListener(listener); |
| | | |
| | | CString strIniFile, strItem; |
| | | strIniFile.Format(_T("%s\\configuration.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | int nIndicatorSize = GetPrivateProfileInt("PageGraph2", _T("IndicatorSize"), 10, strIniFile); |
| | | int nIndicatorMargin = GetPrivateProfileInt("PageGraph2", _T("IndicatorMargin"), 0, strIniFile); |
| | | m_pEqsGraphWnd->SetIndicatorSize(nIndicatorSize); |
| | | m_pEqsGraphWnd->SetIndicatorMargin(nIndicatorMargin); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | |
| | | m_pEqsGraphWnd->AddPin(pItem, OUTPIN, outPin->getName().c_str(), (DWORD_PTR)outPin); |
| | | } |
| | | |
| | | m_pEqsGraphWnd->ShowItemIndicator((DWORD_PTR)pEquipment, pEquipment->hasGlass()); |
| | | UpdateItemIndicators(pEquipment); |
| | | } |
| | | |
| | | void CPageGraph2::UpdateItemIndicators(SERVO::CEquipment* pEquipment) |
| | | { |
| | | for (int i = 0; i < SLOT_MAX; i++) { |
| | | auto pSlot = pEquipment->getSlot(i); |
| | | |
| | | int state = 0; |
| | | if (pSlot->isEnable()) { |
| | | state = pSlot->getContext() != nullptr ? 1 : 2; |
| | | } |
| | | m_pEqsGraphWnd->ShowItemIndicator((DWORD_PTR)pEquipment, state, i); |
| | | } |
| | | } |
| | | |
| | | void CPageGraph2::OnTimer(UINT_PTR nIDEvent) |
| | |
| | | private: |
| | | void InitRxWindows(); |
| | | void AddEqToGraphWnd(SERVO::CEquipment* pEquipment); |
| | | void UpdateItemIndicators(SERVO::CEquipment* pEquipment); |
| | | void SaveEqsGraphData(); |
| | | void GetItemDataFormIni(const char* pszItemName, int& left, int& top); |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // CPageProOverview.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "CPageProdOverview.h" |
| | | #include "afxdialogex.h" |
| | | #include "CPanelProduction.h" |
| | | |
| | | namespace |
| | | { |
| | | constexpr UINT_PTR kTimerRefreshId = 2001; |
| | | constexpr UINT kTimerRefreshIntervalMs = 10000; |
| | | } |
| | | |
| | | IMPLEMENT_DYNAMIC(CPageProdOverview, CDialogEx) |
| | | |
| | | CPageProdOverview::CPageProdOverview(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_PROD_OVERVIEW, pParent) |
| | | , m_clrBackground(RGB(240, 240, 240)) |
| | | { |
| | | } |
| | | |
| | | CPageProdOverview::~CPageProdOverview() |
| | | { |
| | | } |
| | | |
| | | void CPageProdOverview::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | } |
| | | |
| | | void CPageProdOverview::SetBackgroundColor(COLORREF color) |
| | | { |
| | | m_clrBackground = color; |
| | | m_brushBackground.DeleteObject(); |
| | | m_brushBackground.CreateSolidBrush(m_clrBackground); |
| | | if (::IsWindow(m_hWnd)) { |
| | | Invalidate(); |
| | | } |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CPageProdOverview, CDialogEx) |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_DESTROY() |
| | | ON_WM_SIZE() |
| | | ON_WM_TIMER() |
| | | END_MESSAGE_MAP() |
| | | |
| | | BOOL CPageProdOverview::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | |
| | | // 使ç¨èªå®ä¹æ ç¾ |
| | | if (CWnd* pDay = GetDlgItem(IDC_PROD_DAY_OUTPUT)) { |
| | | m_labelDayOut.SubclassWindow(pDay->GetSafeHwnd()); |
| | | m_labelDayOut.setFontSize(28); |
| | | m_labelDayOut.setNoteTextColor(RGB(128, 128, 128)); |
| | | m_labelDayOut.setNote1(_T("ç½ç产åº")); |
| | | m_labelDayOut.setBackground(m_clrBackground); |
| | | m_labelDayOut.setForeground(RGB(18, 18, 18), TRUE); |
| | | } |
| | | if (CWnd* pNight = GetDlgItem(IDC_PROD_NIGHT_OUTPUT)) { |
| | | m_labelNightOut.SubclassWindow(pNight->GetSafeHwnd()); |
| | | m_labelNightOut.setFontSize(28); |
| | | m_labelNightOut.setNoteTextColor(RGB(128, 128, 128)); |
| | | m_labelNightOut.setNote1(_T("å¤ç产åº")); |
| | | m_labelNightOut.setBackground(m_clrBackground); |
| | | m_labelNightOut.setForeground(RGB(18, 18, 18), TRUE); |
| | | } |
| | | if (CWnd* pDayTakt = GetDlgItem(IDC_PROD_DAY_TAKT)) { |
| | | m_labelDayTakt.SubclassWindow(pDayTakt->GetSafeHwnd()); |
| | | m_labelDayTakt.setFontSize(28); |
| | | m_labelDayTakt.setNoteTextColor(RGB(128, 128, 128)); |
| | | m_labelDayTakt.setNote1(_T("ç½çå¹³åTT")); |
| | | m_labelDayTakt.setBackground(m_clrBackground); |
| | | m_labelDayTakt.setForeground(RGB(18, 18, 18), TRUE); |
| | | } |
| | | if (CWnd* pNightTakt = GetDlgItem(IDC_PROD_NIGHT_TAKT)) { |
| | | m_labelNightTakt.SubclassWindow(pNightTakt->GetSafeHwnd()); |
| | | m_labelNightTakt.setFontSize(28); |
| | | m_labelNightTakt.setNoteTextColor(RGB(128, 128, 128)); |
| | | m_labelNightTakt.setNote1(_T("å¤çå¹³åTT")); |
| | | m_labelNightTakt.setBackground(m_clrBackground); |
| | | m_labelNightTakt.setForeground(RGB(18, 18, 18), TRUE); |
| | | } |
| | | |
| | | RefreshData(); |
| | | m_timerId = SetTimer(kTimerRefreshId, kTimerRefreshIntervalMs, nullptr); |
| | | return TRUE; |
| | | } |
| | | |
| | | HBRUSH CPageProdOverview::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) |
| | | { |
| | | HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); |
| | | |
| | | if (nCtlColor == CTLCOLOR_DLG || nCtlColor == CTLCOLOR_STATIC) { |
| | | if (m_brushBackground.GetSafeHandle() == NULL) { |
| | | m_brushBackground.CreateSolidBrush(m_clrBackground); |
| | | } |
| | | pDC->SetBkMode(TRANSPARENT); |
| | | return (HBRUSH)m_brushBackground.GetSafeHandle(); |
| | | } |
| | | |
| | | return hbr; |
| | | } |
| | | |
| | | void CPageProdOverview::OnDestroy() |
| | | { |
| | | if (m_timerId != 0) { |
| | | KillTimer(m_timerId); |
| | | m_timerId = 0; |
| | | } |
| | | CDialogEx::OnDestroy(); |
| | | } |
| | | |
| | | void CPageProdOverview::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | } |
| | | |
| | | void CPageProdOverview::OnTimer(UINT_PTR nIDEvent) |
| | | { |
| | | if (nIDEvent == kTimerRefreshId) { |
| | | RefreshData(); |
| | | } |
| | | CDialogEx::OnTimer(nIDEvent); |
| | | } |
| | | |
| | | void CPageProdOverview::RefreshData() |
| | | { |
| | | auto* pPanel = dynamic_cast<CPanelProduction*>(GetParent()); |
| | | if (pPanel == nullptr) { |
| | | pPanel = dynamic_cast<CPanelProduction*>(GetParent() ? GetParent()->GetParent() : nullptr); |
| | | } |
| | | if (pPanel == nullptr) { |
| | | m_labelDayOut.setText(_T("--")); |
| | | m_labelNightOut.setText(_T("--")); |
| | | m_labelDayTakt.setText(_T("--")); |
| | | m_labelNightTakt.setText(_T("--")); |
| | | return; |
| | | } |
| | | |
| | | ProductionShiftSummary day; |
| | | ProductionShiftSummary night; |
| | | if (!pPanel->TryGetDayNightSummaries(day, night)) { |
| | | m_labelDayOut.setText(_T("--")); |
| | | m_labelNightOut.setText(_T("--")); |
| | | m_labelDayTakt.setText(_T("--")); |
| | | m_labelNightTakt.setText(_T("--")); |
| | | return; |
| | | } |
| | | |
| | | CString text; |
| | | text.Format(_T("%lld"), day.output.pairsTotal); |
| | | m_labelDayOut.setText(text); |
| | | text.Format(_T("%lld"), night.output.pairsTotal); |
| | | m_labelNightOut.setText(text); |
| | | |
| | | text.Format(_T("%.1fs"), day.output.avgTaktSeconds); |
| | | m_labelDayTakt.setText(text); |
| | | text.Format(_T("%.1fs"), night.output.avgTaktSeconds); |
| | | m_labelNightTakt.setText(text); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include <chrono> |
| | | #include "HmLabel.h" |
| | | |
| | | // CPageProOverview å¯¹è¯æ¡ |
| | | class CPageProdOverview : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CPageProdOverview) |
| | | |
| | | public: |
| | | CPageProdOverview(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CPageProdOverview(); |
| | | void SetBackgroundColor(COLORREF color); |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | 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 OnTimer(UINT_PTR nIDEvent); |
| | | |
| | | private: |
| | | void RefreshData(); |
| | | |
| | | private: |
| | | COLORREF m_clrBackground{ RGB(240, 240, 240) }; |
| | | CBrush m_brushBackground; |
| | | UINT_PTR m_timerId = 0; |
| | | CHmLabel m_labelDayOut; |
| | | CHmLabel m_labelNightOut; |
| | | CHmLabel m_labelDayTakt; |
| | | CHmLabel m_labelNightTakt; |
| | | }; |
| | |
| | | #include "Servo.h" |
| | | #include "CPageReport.h" |
| | | #include "afxdialogex.h" |
| | | #include "CReportEditDlg.h" |
| | | #include <algorithm> |
| | | |
| | | |
| | | // CPageReport å¯¹è¯æ¡ |
| | |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_DESTROY() |
| | | ON_WM_SIZE() |
| | | ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CPageReport::OnLvnItemchangedList1) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | |
| | | m_listCtrl.SetItemText(index, 2, item->getVariablesIdsText().c_str()); |
| | | } |
| | | } |
| | | |
| | | void CPageReport::OnCreateBtns() |
| | | { |
| | | const int BTN_W = 80; |
| | | const int BTN_H = 28; |
| | | CreateBtn(_T("æ°å¢"), BTN_W, BTN_H, 2001); |
| | | CreateBtn(_T("å é¤"), BTN_W, BTN_H, 2002)->EnableWindow(FALSE); |
| | | CreateBtn(_T("ç¼è¾"), BTN_W, BTN_H, 2003)->EnableWindow(FALSE); |
| | | } |
| | | |
| | | void CPageReport::OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult) |
| | | { |
| | | LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); |
| | | int nSelCount = m_listCtrl.GetSelectedCount(); |
| | | |
| | | if (CButton* pDel = GetBtnByName("å é¤")) { |
| | | pDel->EnableWindow(nSelCount > 0); |
| | | } |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) { |
| | | pEdit->EnableWindow(nSelCount > 0); |
| | | } |
| | | |
| | | *pResult = 0; |
| | | } |
| | | |
| | | void CPageReport::OnClickedBtn(const char* btnName) |
| | | { |
| | | ASSERT(btnName); |
| | | if (_strcmpi(btnName, "æ°å¢") == 0) { |
| | | int rc = UX_CanExecute(L"addReports"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | |
| | | unsigned int newId = theApp.m_model.m_hsmsPassive.getMaxReportId() + 1; |
| | | std::vector<unsigned int> initVids; |
| | | CReportEditDlg dlg(_T("æ°å¢æ¥å"), static_cast<int>(newId), initVids, this); |
| | | if (dlg.DoModal() != IDOK) return; |
| | | const auto& vids = dlg.GetSelectedVids(); |
| | | |
| | | int ret = theApp.m_model.m_hsmsPassive.addReport(static_cast<int>(newId), vids); |
| | | if (ret == 0) { |
| | | UX_RecordAction(L"addReports"); |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadReports(); |
| | | if (CButton* pDel = GetBtnByName("å é¤")) pDel->EnableWindow(FALSE); |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) pEdit->EnableWindow(FALSE); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("æ°å¢æ¥å失败ï¼å¯è½IDé夿æä»¶åå
¥å¤±è´¥ï¼")); |
| | | } |
| | | } |
| | | else if (_strcmpi(btnName, "å é¤") == 0) { |
| | | POSITION pos = m_listCtrl.GetFirstSelectedItemPosition(); |
| | | if (pos == nullptr) return; |
| | | int nItem = m_listCtrl.GetNextSelectedItem(pos); |
| | | auto pRpt = reinterpret_cast<SERVO::CReport*>(m_listCtrl.GetItemData(nItem)); |
| | | if (pRpt == nullptr) return; |
| | | |
| | | int rc = UX_CanExecute(L"delReports"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | |
| | | int ret = theApp.m_model.m_hsmsPassive.deleteReport((int)pRpt->getReportId()); |
| | | if (ret == 0) { |
| | | UX_RecordAction(L"delReports"); |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadReports(); |
| | | if (CButton* pDel = GetBtnByName("å é¤")) pDel->EnableWindow(FALSE); |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) pEdit->EnableWindow(FALSE); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("å 餿¥å失败")); |
| | | } |
| | | } |
| | | else if (_strcmpi(btnName, "ç¼è¾") == 0) { |
| | | POSITION pos = m_listCtrl.GetFirstSelectedItemPosition(); |
| | | if (pos == nullptr) return; |
| | | int nItem = m_listCtrl.GetNextSelectedItem(pos); |
| | | auto pRpt = reinterpret_cast<SERVO::CReport*>(m_listCtrl.GetItemData(nItem)); |
| | | if (pRpt == nullptr) return; |
| | | |
| | | int rc = UX_CanExecute(L"editReports"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | |
| | | std::vector<unsigned int> vidsExisting = pRpt->getVids(); |
| | | CReportEditDlg dlg(_T("ç¼è¾æ¥å"), (int)pRpt->getReportId(), vidsExisting, this); |
| | | if (dlg.DoModal() != IDOK) return; |
| | | const auto& vids = dlg.GetSelectedVids(); |
| | | |
| | | int ret = theApp.m_model.m_hsmsPassive.updateReport((int)pRpt->getReportId(), vids); |
| | | if (ret == 0) { |
| | | UX_RecordAction(L"editReports"); |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadReports(); |
| | | if (CButton* pDel = GetBtnByName("å é¤")) pDel->EnableWindow(FALSE); |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) pEdit->EnableWindow(FALSE); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("ç¼è¾æ¥å失败ï¼å¯è½æä»¶åå
¥å¤±è´¥ï¼")); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | private: |
| | | CListCtrlEx m_listCtrl; |
| | | void OnCreateBtns() override; |
| | | void OnClickedBtn(const char* btnName) override; |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | |
| | | 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 OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult); |
| | | }; |
| | |
| | | #include "Servo.h" |
| | | #include "CPageVarialbles.h" |
| | | #include "afxdialogex.h" |
| | | #include "CVariableEditDlg2.h" |
| | | |
| | | |
| | | // CPageVarialbles å¯¹è¯æ¡ |
| | |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_DESTROY() |
| | | ON_WM_SIZE() |
| | | ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CPageVarialbles::OnLvnItemchangedList1) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | |
| | | m_listCtrl.SetItemText(index, 4, item->getRemark().c_str()); |
| | | } |
| | | } |
| | | |
| | | void CPageVarialbles::OnCreateBtns() |
| | | { |
| | | const int BTN_W = 80; |
| | | const int BTN_H = 28; |
| | | CreateBtn(_T("æ°å¢"), BTN_W, BTN_H, 1001); |
| | | CreateBtn(_T("å é¤"), BTN_W, BTN_H, 1002)->EnableWindow(FALSE); |
| | | CreateBtn(_T("ç¼è¾"), BTN_W, BTN_H, 1003)->EnableWindow(FALSE); |
| | | } |
| | | |
| | | void CPageVarialbles::OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult) |
| | | { |
| | | LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); |
| | | int nSelCount = m_listCtrl.GetSelectedCount(); |
| | | |
| | | // æ ¹æ®éä¸ç¶æå¯ç¨/ç¦ç¨æé® |
| | | if (CButton* pDel = GetBtnByName("å é¤")) { |
| | | pDel->EnableWindow(nSelCount > 0); |
| | | } |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) { |
| | | pEdit->EnableWindow(nSelCount > 0); |
| | | } |
| | | |
| | | *pResult = 0; |
| | | } |
| | | |
| | | void CPageVarialbles::OnClickedBtn(const char* btnName) |
| | | { |
| | | ASSERT(btnName); |
| | | if (_strcmpi(btnName, "æ°å¢") == 0) { |
| | | int rc = UX_CanExecute(L"addVarialbles"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | unsigned int newId = theApp.m_model.m_hsmsPassive.getMaxVariableId(); |
| | | int newIdInt = static_cast<int>(newId + 1); |
| | | CVariableEditDlg2 dlg(_T("æ°å¢åé"), newIdInt, _T("U1"), _T(""), _T(""), this); |
| | | if (dlg.DoModal() != IDOK) return; |
| | | CString name = dlg.GetNameText(); |
| | | CString fmt = dlg.GetTypeText(); |
| | | CString remark = dlg.GetRemark(); |
| | | |
| | | int ret = theApp.m_model.m_hsmsPassive.addVariable(CT2A(name), CT2A(fmt), CT2A(remark), newIdInt); |
| | | if (ret == 0) { |
| | | UX_RecordAction(L"addVarialbles"); |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadVariables(); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("æ°å¢åéå¤±è´¥ï¼æ ¼å¼æ¯å¦æ£ç¡®ï¼(U1/U2/I2/A20/A50/L)")); |
| | | } |
| | | } |
| | | else if (_strcmpi(btnName, "å é¤") == 0) { |
| | | POSITION pos = m_listCtrl.GetFirstSelectedItemPosition(); |
| | | if (pos == nullptr) return; |
| | | int nItem = m_listCtrl.GetNextSelectedItem(pos); |
| | | auto pVar = reinterpret_cast<SERVO::CVariable*>(m_listCtrl.GetItemData(nItem)); |
| | | if (pVar == nullptr) return; |
| | | |
| | | int rc = UX_CanExecute(L"delVarialbles"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | int ret = theApp.m_model.m_hsmsPassive.deleteVariable(pVar->getVarialbleId()); |
| | | if (ret == 0) { |
| | | UX_RecordAction(L"delVarialbles"); |
| | | |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadVariables(); |
| | | if (CButton* pDel = GetBtnByName("å é¤")) pDel->EnableWindow(FALSE); |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) pEdit->EnableWindow(FALSE); |
| | | } |
| | | } |
| | | else if (_strcmpi(btnName, "ç¼è¾") == 0) { |
| | | POSITION pos = m_listCtrl.GetFirstSelectedItemPosition(); |
| | | if (pos == nullptr) return; |
| | | int nItem = m_listCtrl.GetNextSelectedItem(pos); |
| | | auto pVar = reinterpret_cast<SERVO::CVariable*>(m_listCtrl.GetItemData(nItem)); |
| | | if (pVar == nullptr) return; |
| | | |
| | | int rc = UX_CanExecute(L"editVarialbles"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | CVariableEditDlg2 dlg(_T("ç¼è¾åé"), |
| | | pVar->getVarialbleId(), |
| | | CString(CA2T(SERVO::CVariable::formatToString(pVar->getFormat()).c_str())), |
| | | CString(CA2T(pVar->getName().c_str())), |
| | | CString(CA2T(pVar->getRemark().c_str())), |
| | | this); |
| | | if (dlg.DoModal() != IDOK) return; |
| | | CString name = dlg.GetNameText(); |
| | | CString fmt = dlg.GetTypeText(); |
| | | CString remark = dlg.GetRemark(); |
| | | |
| | | int ret = theApp.m_model.m_hsmsPassive.updateVariable(pVar->getVarialbleId(), CT2A(name), CT2A(fmt), CT2A(remark)); |
| | | if (ret == 0) { |
| | | UX_RecordAction(L"editVarialbles"); |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadVariables(); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("ç¼è¾åéå¤±è´¥ï¼æ ¼å¼æ¯å¦æ£ç¡®ï¼(U1/U2/I2/A20/A50/L)")); |
| | | } |
| | | } |
| | | } |
| | |
| | | virtual ~CPageVarialbles(); |
| | | virtual void OnApply(); |
| | | void loadVariables(); |
| | | virtual void OnCreateBtns(); |
| | | |
| | | private: |
| | | CListCtrlEx m_listCtrl; |
| | | |
| | | protected: |
| | | virtual void OnClickedBtn(const char* btnName) override; |
| | | |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | |
| | | 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 OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult); |
| | | }; |
| | |
| | | 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; |
| | | m_pAccordionWnd = nullptr; |
| | | m_pPageProdOverview = nullptr; |
| | | m_pPageCtrlState = 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(); |
| | | |
| | | CString strExpandIcon, strCloseIcon; |
| | | strExpandIcon.Format(_T("%s\\res\\arrow_down.ico"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | strCloseIcon.Format(_T("%s\\res\\arrow_right.ico"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | |
| | | m_pAccordionWnd = CAccordionWnd::FromHandle(GetDlgItem(IDC_ACCORDION_WND1)->m_hWnd); |
| | | m_pAccordionWnd->SetBkgndColor(m_crBkgnd); |
| | | m_pAccordionWnd->SetFrameColor(RGB(220, 220, 200), TRUE); |
| | | m_pAccordionWnd->Setpadding(PADDING_LEFT, 2); |
| | | m_pAccordionWnd->Setpadding(PADDING_TOP, 2); |
| | | m_pAccordionWnd->Setpadding(PADDING_RIGHT, 2); |
| | | m_pAccordionWnd->Setpadding(PADDING_BOTTOM, 2); |
| | | m_pAccordionWnd->LoadExpandIcon(strExpandIcon, strCloseIcon); |
| | | |
| | | m_pPageCtrlState = new CPageCtrlState(); |
| | | m_pPageCtrlState->SetBackgroundColor(m_crBkgnd); |
| | | m_pPageCtrlState->Create(IDD_PROD_CTRL_STATE, GetDlgItem(IDC_ACCORDION_WND1)); |
| | | m_pPageCtrlState->ShowWindow(SW_HIDE); |
| | | m_pAccordionWnd->AddItem("ç¶æ", m_pPageCtrlState, 120, TRUE, TRUE); |
| | | |
| | | m_pPageProdOverview = new CPageProdOverview(); |
| | | m_pPageProdOverview->SetBackgroundColor(m_crBkgnd); |
| | | m_pPageProdOverview->Create(IDD_PROD_OVERVIEW, GetDlgItem(IDC_ACCORDION_WND1)); |
| | | m_pPageProdOverview->ShowWindow(SW_HIDE); |
| | | m_pAccordionWnd->AddItem("ç产æ»è§", m_pPageProdOverview, 280, TRUE, TRUE); |
| | | |
| | | 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_pPageCtrlState != nullptr) { |
| | | m_pPageCtrlState->DestroyWindow(); |
| | | delete m_pPageCtrlState; |
| | | m_pPageCtrlState = nullptr; |
| | | } |
| | | if (m_pPageProdOverview != nullptr) { |
| | | m_pPageProdOverview->DestroyWindow(); |
| | | delete m_pPageProdOverview; |
| | | m_pPageProdOverview = nullptr; |
| | | } |
| | | |
| | | 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()); |
| | | |
| | | pItem = GetDlgItem(IDC_ACCORDION_WND1); |
| | | pItem->MoveWindow(5, 5, rcClient.Width() - 10, rcClient.Height() - 10); |
| | | } |
| | | |
| | | #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::TryGetDayNightSummaries(ProductionShiftSummary& outDay, ProductionShiftSummary& outNight) |
| | | { |
| | | CSingleLock lock(&m_csShiftSummary, TRUE); |
| | | if (!m_bShiftSummaryValid) return FALSE; |
| | | outDay = m_daySummary; |
| | | outNight = m_nightSummary; |
| | | 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 daySummary; |
| | | ProductionShiftSummary nightSummary; |
| | | if (ProductionStats::ComputeDayNightSummaries(theApp.m_model.m_configuration, daySummary, nightSummary)) { |
| | | CSingleLock lock(&self->m_csShiftSummary, TRUE); |
| | | self->m_daySummary = std::move(daySummary); |
| | | self->m_nightSummary = std::move(nightSummary); |
| | | self->m_bShiftSummaryValid = TRUE; |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | void CPanelProduction::OnTimer(UINT_PTR nIDEvent) |
| | | { |
| | | // TODO: 卿¤æ·»å æ¶æ¯å¤çç¨åºä»£ç å/æè°ç¨é»è®¤å¼ |
| | | CDialogEx::OnTimer(nIDEvent); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "BlButton.h" |
| | | #include <afxmt.h> |
| | | #include "AccordionWnd.h" |
| | | #include "ProductionStats.h" |
| | | #include "CPageProdOverview.h" |
| | | #include "CPageCtrlState.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; |
| | | CAccordionWnd* m_pAccordionWnd; |
| | | |
| | | // Production shift summaries (updated by background thread) |
| | | ProductionShiftSummary m_daySummary; |
| | | ProductionShiftSummary m_nightSummary; |
| | | BOOL m_bShiftSummaryValid; |
| | | CCriticalSection m_csShiftSummary; |
| | | CWinThread* m_pStatsThread; |
| | | CEvent m_evStopStats; |
| | | CPageProdOverview* m_pPageProdOverview; |
| | | CPageCtrlState* m_pPageCtrlState; |
| | | |
| | | 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 snapshots for UI timer display |
| | | BOOL TryGetDayNightSummaries(ProductionShiftSummary& outDay, ProductionShiftSummary& outNight); |
| | | |
| | | private: |
| | | static UINT AFX_CDECL StatsThreadProc(LPVOID pParam); |
| | | void StartStatsThread(); |
| | | void StopStatsThread(); |
| | | public: |
| | | afx_msg void OnTimer(UINT_PTR nIDEvent); |
| | | }; |
| | |
| | | return m_nValueType; |
| | | } |
| | | |
| | | int CParam::getIntValue() |
| | | int CParam::getIntValue() const |
| | | { |
| | | return m_nValue; |
| | | } |
| | |
| | | m_nValue = value; |
| | | } |
| | | |
| | | double CParam::getDoubleValue() |
| | | double CParam::getDoubleValue() const |
| | | { |
| | | if(m_nValueType == PVT_DOUBLE) |
| | | return m_fValue; |
| | |
| | | std::string& getName(); |
| | | std::string& getUnit(); |
| | | int getValueType(); |
| | | int getIntValue(); |
| | | int getIntValue() const; |
| | | void setIntValue(int value); |
| | | double getDoubleValue(); |
| | | double getDoubleValue() const; |
| | | void setDoubleValue(double value); |
| | | void Serialize(CArchive& ar); |
| | | |
| | |
| | | ASSERT(m_pEquipment); |
| | | m_pEquipment->onStepEvent(this, STEP_EVENT_READDATA); |
| | | } |
| | | if (m_bReadContinue) continue; |
| | | |
| | | // 0426æ°å¢ |
| | | // 1.1ï¼åreturn code or data |
| | |
| | | |
| | | public: |
| | | unsigned WorkingProc(); |
| | | virtual void setReadContinue(BOOL bContinue) { m_bReadContinue = bContinue; }; |
| | | virtual void setWriteSignalDev(int dev); |
| | | virtual void setReturnDev(int dev); |
| | | virtual void onReadSignal(int nSignalType); |
| | |
| | | char m_szReturnBuf[1024]; |
| | | int m_nReturnDataSize; |
| | | int m_nReturnDevNo; |
| | | BOOL m_bReadContinue{ FALSE }; |
| | | }; |
| | | } |
| | | |
| | |
| | | m_nReportId = 0; |
| | | } |
| | | |
| | | CReport::CReport(unsigned int reportId, std::vector<unsigned int>& vids) |
| | | CReport::CReport(unsigned int reportId, const std::vector<unsigned int>& vids) |
| | | { |
| | | m_nReportId = reportId; |
| | | for (auto vid : vids) { |
| | | m_vids.push_back(vid); |
| | | } |
| | | m_vids = vids; |
| | | } |
| | | |
| | | CReport::~CReport() |
| | |
| | | { |
| | | public: |
| | | CReport(); |
| | | CReport(unsigned int reportId, std::vector<unsigned int>& vids); |
| | | CReport(unsigned int reportId, const std::vector<unsigned int>& vids); |
| | | virtual ~CReport(); |
| | | |
| | | public: |
| | |
| | | std::vector<CVariable*>& getVariables(); |
| | | std::string getVariablesIdsText(); |
| | | bool getVariableName(unsigned int vid, std::string& strName); |
| | | const std::vector<unsigned int>& getVids() const { return m_vids; } |
| | | |
| | | private: |
| | | unsigned int m_nReportId; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "CReportEditDlg.h" |
| | | #include "Servo.h" |
| | | #include "resource.h" |
| | | #include <algorithm> |
| | | |
| | | IMPLEMENT_DYNAMIC(CReportEditDlg, CDialogEx) |
| | | |
| | | CReportEditDlg::CReportEditDlg(const CString& title, int rptId, const std::vector<unsigned int>& vids, CWnd* pParent) |
| | | : CDialogEx(IDD_DIALOG_REPORT_EDIT, pParent) |
| | | , m_strTitle(title) |
| | | , m_rptId(rptId) |
| | | , m_vids(vids) |
| | | { |
| | | } |
| | | |
| | | CReportEditDlg::~CReportEditDlg() |
| | | { |
| | | } |
| | | |
| | | void CReportEditDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_EDIT_RPT_ID, m_editId); |
| | | DDX_Control(pDX, IDC_LIST_RPT_VARS, m_listVars); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CReportEditDlg, CDialogEx) |
| | | END_MESSAGE_MAP() |
| | | |
| | | BOOL CReportEditDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | SetWindowText(m_strTitle); |
| | | |
| | | CString strId; |
| | | strId.Format(_T("%d"), m_rptId); |
| | | m_editId.SetWindowText(strId); |
| | | m_editId.SetReadOnly(TRUE); |
| | | |
| | | // åå§åå表 |
| | | m_listVars.SetExtendedStyle(m_listVars.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES); |
| | | m_listVars.InsertColumn(0, _T("ID"), LVCFMT_LEFT, 60); |
| | | m_listVars.InsertColumn(1, _T("åç§°"), LVCFMT_LEFT, 140); |
| | | m_listVars.InsertColumn(2, _T("æ ¼å¼"), LVCFMT_LEFT, 80); |
| | | |
| | | auto& vars = theApp.m_model.m_hsmsPassive.getVariables(); |
| | | for (int i = 0; i < (int)vars.size(); ++i) { |
| | | auto v = vars[i]; |
| | | if (v == nullptr) continue; |
| | | int idx = m_listVars.InsertItem(m_listVars.GetItemCount(), std::to_string(v->getVarialbleId()).c_str()); |
| | | m_listVars.SetItemText(idx, 1, v->getName().c_str()); |
| | | m_listVars.SetItemText(idx, 2, SERVO::CVariable::formatToString(v->getFormat()).c_str()); |
| | | m_listVars.SetItemData(idx, (DWORD_PTR)v->getVarialbleId()); |
| | | if (std::find(m_vids.begin(), m_vids.end(), v->getVarialbleId()) != m_vids.end()) { |
| | | m_listVars.SetCheck(idx, TRUE); |
| | | } |
| | | } |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CReportEditDlg::OnOK() |
| | | { |
| | | std::vector<unsigned int> selected; |
| | | int count = m_listVars.GetItemCount(); |
| | | for (int i = 0; i < count; ++i) { |
| | | if (m_listVars.GetCheck(i)) { |
| | | selected.push_back((unsigned int)m_listVars.GetItemData(i)); |
| | | } |
| | | } |
| | | if (selected.empty()) { |
| | | AfxMessageBox(_T("è³å°éæ©ä¸ä¸ªåé")); |
| | | return; |
| | | } |
| | | m_vids.swap(selected); |
| | | CDialogEx::OnOK(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | |
| | | // æ¥åç¼è¾å¯¹è¯æ¡ï¼æ°å¢/ç¼è¾å
±ç¨ï¼ |
| | | class CReportEditDlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CReportEditDlg) |
| | | |
| | | public: |
| | | CReportEditDlg(const CString& title, int rptId, const std::vector<unsigned int>& vids, CWnd* pParent = nullptr); |
| | | virtual ~CReportEditDlg(); |
| | | |
| | | int GetReportId() const { return m_rptId; } |
| | | const std::vector<unsigned int>& GetSelectedVids() const { return m_vids; } |
| | | |
| | | protected: |
| | | virtual BOOL OnInitDialog() override; |
| | | virtual void DoDataExchange(CDataExchange* pDX) override; |
| | | afx_msg void OnOK(); |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | |
| | | private: |
| | | CString m_strTitle; |
| | | int m_rptId; |
| | | std::vector<unsigned int> m_vids; |
| | | |
| | | CEdit m_editId; |
| | | CListCtrl m_listVars; |
| | | }; |
| | |
| | | |
| | | int CSVData::serialize(char* pszBuffer, int nBufferSize) |
| | | { |
| | | if (nBufferSize < 133) return -1; |
| | | if (nBufferSize < 133 * 2) return -1; |
| | | |
| | | int index = 0; |
| | | CToolUnits::convertString(&pszBuffer[index], 8, m_strTime); |
| | | index += 8; |
| | | CToolUnits::convertString(&pszBuffer[index], 8 * 2, m_strTime); |
| | | index += 8 * 2; |
| | | |
| | | memcpy(&pszBuffer[index], m_svRawData.data(), 125); |
| | | index += 125; |
| | | memcpy(&pszBuffer[index], m_svRawData.data(), 125 * 2); |
| | | index += 125 * 2; |
| | | |
| | | return 133; |
| | | return 133 * 2; |
| | | } |
| | | |
| | | int CSVData::unserialize(const char* pszBuffer, int nBufferSize) |
| | | { |
| | | if (nBufferSize < 133) return -1; |
| | | if (pszBuffer == nullptr) return -1; |
| | | if (nBufferSize < 133 * 2) return -1; |
| | | |
| | | int index = 0; |
| | | CSVData svData; |
| | | CToolUnits::convertString(&pszBuffer[index], 8 * 2, m_strTime); |
| | | index += 8 * 2; |
| | | |
| | | m_svRawData.clear(); |
| | | m_svRawData.insert(m_svRawData.end(), (uint8_t*)(&pszBuffer[index]), (uint8_t*)(pszBuffer)+(125 * 2)); |
| | | if (nBufferSize < index + 125 * 2) return -1; |
| | | m_svRawData.insert( |
| | | m_svRawData.end(), |
| | | (const uint8_t*)&pszBuffer[index], |
| | | (const uint8_t*)&pszBuffer[index + 125 * 2]); |
| | | index += 125 * 2; |
| | | |
| | | return 133; |
| | | return 133 * 2; |
| | | } |
| | | } |
| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "CServoUtilsTool.h" |
| | | #include "Common.h" |
| | | |
| | | |
| | | namespace SERVO { |
| | | static std::unordered_map<int, std::vector<std::string>> EQ_DATA_TYPES = { |
| | | {EQ_ID_Bonder1, { |
| | | "æ°ååå", "ä¸è
åå", "管éç空è§å¼", "è
ä½ç空è§å¼", |
| | | "ä¸è
温度1", "ä¸è
温度2", "ä¸è
温度3", "ä¸è
温度4", |
| | | "ä¸è
温度5", "ä¸è
温度6", "ä¸è
温度1", "ä¸è
温度2", |
| | | "ä¸è
温度3", "ä¸è
温度4", "ä¸è
温度5", "ä¸è
温度6" |
| | | {MID_Bonder1, { |
| | | "æ°ååå", "ä¸è
åå", "管éç空è§å¼", "è
ä½ç空è§å¼", |
| | | "ä¸è
温度1", "ä¸è
温度2", "ä¸è
温度3", "ä¸è
温度4", |
| | | "ä¸è
温度5", "ä¸è
温度6", "ä¸è
温度1", "ä¸è
温度2", |
| | | "ä¸è
温度3", "ä¸è
温度4", "ä¸è
温度5", "ä¸è
温度6" |
| | | }}, |
| | | {EQ_ID_Bonder2, { |
| | | "æ°ååå", "ä¸è
åå", "管éç空è§å¼", "è
ä½ç空è§å¼", |
| | | "ä¸è
温度1", "ä¸è
温度2", "ä¸è
温度3", "ä¸è
温度4", |
| | | "ä¸è
温度5", "ä¸è
温度6", "ä¸è
温度1", "ä¸è
温度2", |
| | | "ä¸è
温度3", "ä¸è
温度4", "ä¸è
温度5", "ä¸è
温度6" |
| | | {MID_Bonder2, { |
| | | "æ°ååå", "ä¸è
åå", "管éç空è§å¼", "è
ä½ç空è§å¼", |
| | | "ä¸è
温度1", "ä¸è
温度2", "ä¸è
温度3", "ä¸è
温度4", |
| | | "ä¸è
温度5", "ä¸è
温度6", "ä¸è
温度1", "ä¸è
温度2", |
| | | "ä¸è
温度3", "ä¸è
温度4", "ä¸è
温度5", "ä¸è
温度6" |
| | | }}, |
| | | {EQ_ID_VACUUMBAKE, { |
| | | "Aè
ç空è§å¼", "Aè
温æ§1", "Aè
温æ§2", "Aè
温æ§4", |
| | | "Aè
温æ§5", "Aè
温æ§6", "Aè
温æ§7", "Bè
ç空è§å¼", |
| | | "Bè
温æ§1", "Bè
温æ§2", "Bè
温æ§4", "Bè
温æ§5", |
| | | "Bè
温æ§6", "Bè
温æ§7" |
| | | {MID_VacuumBakeA, { |
| | | "ç空è§å¼", "温æ§1", "温æ§2", "温æ§4", |
| | | "温æ§5", "温æ§6", "温æ§7" |
| | | }}, |
| | | {EQ_ID_BAKE_COOLING, { |
| | | "Açç¤æ¸©æ§1", "Açç¤æ¸©æ§2", "Açç¤æ¸©æ§4", "Açç¤æ¸©æ§5", |
| | | "Açç¤æ¸©æ§6", "Açç¤æ¸©æ§7", "Bçç¤æ¸©æ§1", "Bçç¤æ¸©æ§2", |
| | | "Bçç¤æ¸©æ§4", "Bçç¤æ¸©æ§5", "Bçç¤æ¸©æ§6", "Bçç¤æ¸©æ§7" |
| | | {MID_VacuumBakeB, { |
| | | "ç空è§å¼", "温æ§1", "温æ§2", "温æ§4", |
| | | "温æ§5", "温æ§6", "温æ§7" |
| | | }}, |
| | | {MID_BakeCoolingA, { |
| | | "çç¤æ¸©æ§1", "çç¤æ¸©æ§2", "çç¤æ¸©æ§4", "çç¤æ¸©æ§5", |
| | | "çç¤æ¸©æ§6", "çç¤æ¸©æ§7" |
| | | }}, |
| | | {MID_BakeCoolingB, { |
| | | "çç¤æ¸©æ§1", "çç¤æ¸©æ§2", "çç¤æ¸©æ§4", "çç¤æ¸©æ§5", |
| | | "çç¤æ¸©æ§6", "çç¤æ¸©æ§7" |
| | | }} |
| | | }; |
| | | |
| | |
| | | } |
| | | |
| | | if (eqid == EQ_ID_VACUUMBAKE) { |
| | | if (unit == 0) return "çç¤Aè
"; |
| | | if (unit == 1) return "çç¤Bè
"; |
| | | if (unit == 0) return "çç¤Aè
"; |
| | | if (unit == 1) return "çç¤Bè
"; |
| | | } |
| | | |
| | | if (eqid == EQ_ID_Bonder1) { |
| | |
| | | |
| | | if (eqid == EQ_ID_BAKE_COOLING) { |
| | | |
| | | if (unit == 0) return "åçç¤Aè
"; |
| | | if (unit == 1) return "å·å´A"; |
| | | if (unit == 2) return "åçç¤Bè
"; |
| | | if (unit == 3) return "å·å´B"; |
| | | if (unit == 0) return "åçç¤Aè
"; |
| | | if (unit == 1) return "å·å´A"; |
| | | if (unit == 2) return "åçç¤Bè
"; |
| | | if (unit == 3) return "å·å´B"; |
| | | } |
| | | |
| | | if (eqid == EQ_ID_MEASUREMENT) { |
| | |
| | | |
| | | if (eqid == EQ_ID_VACUUMBAKE) { |
| | | if (unit == 0) { |
| | | sprintf_s(szBuffer, 256, "çç¤Aè
(Slot%d)", slot); |
| | | sprintf_s(szBuffer, 256, "çç¤Aè
(Slot%d)", slot); |
| | | return std::string(szBuffer); |
| | | } |
| | | if (unit == 1) { |
| | | sprintf_s(szBuffer, 256, "çç¤Bè
(Slot%d)", slot); |
| | | sprintf_s(szBuffer, 256, "çç¤Bè
(Slot%d)", slot); |
| | | return std::string(szBuffer); |
| | | } |
| | | } |
| | |
| | | |
| | | if (eqid == EQ_ID_BAKE_COOLING) { |
| | | |
| | | if (slot == 0) return "åçç¤Aè
"; |
| | | if (slot == 1) return "å·å´A"; |
| | | if (slot == 2) return "åçç¤Bè
"; |
| | | if (slot == 3) return "å·å´B"; |
| | | if (slot == 0) return "åçç¤Aè
"; |
| | | if (slot == 1) return "å·å´A"; |
| | | if (slot == 2) return "åçç¤Bè
"; |
| | | if (slot == 3) return "å·å´B"; |
| | | } |
| | | |
| | | if (eqid == EQ_ID_MEASUREMENT) { |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include "ServoCommo.h" |
| | | #include "CGlass.h" |
| | | |
| | | |
| | | namespace SERVO { |
| | | constexpr uint32_t MID_Bonder1 = 1001; |
| | | constexpr uint32_t MID_Bonder2 = 1002; |
| | | constexpr uint32_t MID_VacuumBakeA = 1003; |
| | | constexpr uint32_t MID_VacuumBakeB = 1004; |
| | | constexpr uint32_t MID_BakeCoolingA = 1005; |
| | | constexpr uint32_t MID_BakeCoolingB = 1006; |
| | | |
| | | class CServoUtilsTool |
| | | { |
| | | public: |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "CUserEdit2Dlg.h" |
| | | #include "CUserManager2.h" |
| | | #include "resource.h" |
| | | |
| | | IMPLEMENT_DYNAMIC(CUserEdit2Dlg, CDialogEx) |
| | | |
| | | CUserEdit2Dlg::CUserEdit2Dlg(bool editMode, CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_USER_EDIT2, pParent) |
| | | { |
| | | m_bEditMode = editMode; |
| | | } |
| | | |
| | | CUserEdit2Dlg::~CUserEdit2Dlg() |
| | | { |
| | | } |
| | | |
| | | void CUserEdit2Dlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Text(pDX, IDC_EDIT_USER_ACCOUNT, m_strUsername); |
| | | DDX_Text(pDX, IDC_EDIT_USER_DISPLAY, m_strDisplayName); |
| | | DDX_Text(pDX, IDC_EDIT_USER_PASSWORD, m_strPassword); |
| | | DDX_CBString(pDX, IDC_COMBO_USER_ROLE, m_strRole); |
| | | DDX_Check(pDX, IDC_CHECK_USER_ENABLED, m_bEnabled); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CUserEdit2Dlg, CDialogEx) |
| | | END_MESSAGE_MAP() |
| | | |
| | | BOOL CUserEdit2Dlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | if (m_bEditMode) { |
| | | if (auto pEdit = GetDlgItem(IDC_EDIT_USER_ACCOUNT)) { |
| | | pEdit->EnableWindow(FALSE); |
| | | } |
| | | } |
| | | |
| | | UpdateData(FALSE); |
| | | |
| | | auto roles = CUserManager2::getInstance().getRoles(); |
| | | CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_USER_ROLE); |
| | | if (pCombo) { |
| | | int selected = -1; |
| | | for (const auto& role : roles) { |
| | | CString text(role.name.c_str()); |
| | | int idx = pCombo->AddString(text); |
| | | if (selected == -1 && m_strRole.CompareNoCase(text) == 0) { |
| | | selected = idx; |
| | | } |
| | | } |
| | | |
| | | if (selected >= 0) { |
| | | pCombo->SetCurSel(selected); |
| | | } |
| | | else if (pCombo->GetCount() > 0) { |
| | | pCombo->SetCurSel(0); |
| | | CString text; |
| | | pCombo->GetLBText(0, text); |
| | | if (m_strRole.IsEmpty()) { |
| | | m_strRole = text; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (auto pPwd = GetDlgItem(IDC_EDIT_USER_PASSWORD)) { |
| | | pPwd->EnableWindow(!m_bEditMode); |
| | | if (m_bEditMode) { |
| | | pPwd->SetWindowText(_T("")); |
| | | } |
| | | } |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CUserEdit2Dlg::OnOK() |
| | | { |
| | | UpdateData(TRUE); |
| | | |
| | | CString user = m_strUsername; |
| | | user.Trim(); |
| | | CString role = m_strRole; |
| | | role.Trim(); |
| | | |
| | | CString password = m_strPassword; |
| | | password.Trim(); |
| | | |
| | | if (m_bEditMode) { |
| | | password.Empty(); |
| | | } |
| | | |
| | | if (!m_bEditMode) { |
| | | if (user.IsEmpty()) { |
| | | AfxMessageBox(_T("请è¾å
¥è´¦å·")); |
| | | return; |
| | | } |
| | | |
| | | if (password.IsEmpty()) { |
| | | AfxMessageBox(_T("请è¾å
¥å¯ç ")); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | if (role.IsEmpty()) { |
| | | AfxMessageBox(_T("è¯·éæ©è§è²")); |
| | | return; |
| | | } |
| | | |
| | | if (auto pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_USER_ROLE)) { |
| | | int sel = pCombo->GetCurSel(); |
| | | if (sel != CB_ERR) { |
| | | CString text; |
| | | pCombo->GetLBText(sel, text); |
| | | if (!text.IsEmpty()) { |
| | | m_strRole = text; |
| | | } |
| | | } |
| | | } |
| | | |
| | | m_strUsername = user; |
| | | m_strPassword = password; |
| | | CDialogEx::OnOK(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | |
| | | class CUserEdit2Dlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CUserEdit2Dlg) |
| | | |
| | | public: |
| | | CUserEdit2Dlg(bool editMode = false, CWnd* pParent = nullptr); |
| | | virtual ~CUserEdit2Dlg(); |
| | | |
| | | CString m_strUsername; |
| | | CString m_strDisplayName; |
| | | CString m_strPassword; |
| | | CString m_strRole; |
| | | BOOL m_bEnabled = TRUE; |
| | | bool m_bEditMode = false; |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnOK(); |
| | | DECLARE_MESSAGE_MAP() |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "CUserManager2.h" |
| | | #include "ToolUnits.h" |
| | | #include <vector> |
| | | #include <map> |
| | | #include <utility> |
| | | #include <algorithm> |
| | | #include <sstream> |
| | | #include <cwchar> |
| | | |
| | | std::vector<std::wstring> SplitLines(const std::wstring& text) |
| | | { |
| | | std::wstringstream ss(text); std::vector<std::wstring> v; std::wstring line; while (std::getline(ss, line)) v.push_back(line); return v; |
| | | } |
| | | |
| | | std::vector<std::wstring> SplitByDelimiter(const std::wstring& text, wchar_t delimiter) |
| | | { |
| | | std::vector<std::wstring> parts; |
| | | size_t start = 0; |
| | | while (start <= text.length()) { |
| | | size_t pos = text.find(delimiter, start); |
| | | if (pos == std::wstring::npos) { |
| | | parts.push_back(text.substr(start)); |
| | | break; |
| | | } |
| | | |
| | | parts.push_back(text.substr(start, pos - start)); |
| | | start = pos + 1; |
| | | } |
| | | |
| | | return parts; |
| | | } |
| | | |
| | | template<typename Fn> |
| | | std::wstring ReadBufferVia(Fn fn) |
| | | { |
| | | int need = fn(nullptr, 0); if (need <= 0) return L""; |
| | | std::wstring buf; buf.resize((size_t)need); |
| | | int rc = fn(buf.data(), need); |
| | | if (rc == 0) { if (!buf.empty() && buf.back() == L'\0') buf.pop_back(); return buf; } |
| | | return L""; |
| | | } |
| | | |
| | | // è·ååä¾å®ä¾ |
| | | CUserManager2& CUserManager2::getInstance() { |
| | | static CUserManager2 instance; |
| | | return instance; |
| | | } |
| | | |
| | | CUserManager2::CUserManager2() |
| | | { |
| | | |
| | | } |
| | | |
| | | CUserManager2::~CUserManager2() |
| | | { |
| | | |
| | | } |
| | | |
| | | void CUserManager2::init(const char* pszDir) |
| | | { |
| | | std::wstring dir = CToolUnits::AnsiToWString(std::string(pszDir)); |
| | | UX_Init(dir.c_str()); |
| | | |
| | | wchar_t buffer[1024]; |
| | | UX_GetUsers(buffer, 1024); |
| | | bool hasAny = false; |
| | | for (auto& ln : SplitLines(buffer)) { if (!ln.empty()) { hasAny = true; break; } } |
| | | if (!hasAny) { |
| | | const wchar_t* roles = L"Admin:100\nEE:80\nPE:50\nOperator:10\n"; |
| | | (void)UX_SetRoleDefinitions(roles); |
| | | (void)UX_AddUser(L"admin", L"Administrator", L"admin123", L"Admin"); |
| | | |
| | | UX_DefineAction(L"start", L"å¯å¨æºå°", L"Operator"); |
| | | UX_DefineAction(L"stop", L"åæº", L"Operator"); |
| | | UX_DefineAction(L"recipe", L"ç¼è¾é
æ¹", L"PE"); |
| | | UX_DefineAction(L"delVarialbles", L"å é¤åé", L"PE"); |
| | | UX_DefineAction(L"addVarialbles", L"æ°å¢åé", L"PE"); |
| | | UX_DefineAction(L"editVarialbles", L"ç¼è¾åé", L"PE"); |
| | | UX_DefineAction(L"addReports", L"æ°å¢Report", L"PE"); |
| | | UX_DefineAction(L"editReports", L"ç¼è¾Report", L"PE"); |
| | | UX_DefineAction(L"delReports", L"å é¤Report", L"PE"); |
| | | UX_DefineAction(L"addEvents", L"æ°å¢Event", L"PE"); |
| | | UX_DefineAction(L"editEvents", L"ç¼è¾Event", L"PE"); |
| | | UX_DefineAction(L"delEvents", L"å é¤Event", L"PE"); |
| | | } |
| | | // ç¡®ä¿æéå®ä¹åå¨ï¼å¹çï¼ |
| | | UX_DefineAction(L"addVarialbles", L"æ°å¢åé", L"PE"); |
| | | UX_DefineAction(L"editVarialbles", L"ç¼è¾åé", L"PE"); |
| | | UX_DefineAction(L"delVarialbles", L"å é¤åé", L"PE"); |
| | | UX_DefineAction(L"addReports", L"æ°å¢Report", L"PE"); |
| | | UX_DefineAction(L"editReports", L"ç¼è¾Report", L"PE"); |
| | | UX_DefineAction(L"delReports", L"å é¤Report", L"PE"); |
| | | UX_DefineAction(L"delEvents", L"å é¤Event", L"PE"); |
| | | UX_DefineAction(L"addEvents", L"æ°å¢Event", L"PE"); |
| | | UX_DefineAction(L"editEvents", L"ç¼è¾Event", L"PE"); |
| | | } |
| | | |
| | | bool CUserManager2::login(const char* pszAccount, const char* pszPwd) |
| | | { |
| | | std::wstring strUser, strPwd; |
| | | strUser = CToolUnits::AnsiToWString(std::string(pszAccount)); |
| | | strPwd = CToolUnits::AnsiToWString(std::string(pszPwd)); |
| | | int rc = UX_Login(strUser.c_str(), strPwd.c_str()); |
| | | return rc == UX_OK; |
| | | } |
| | | |
| | | bool CUserManager2::isLoggedIn() |
| | | { |
| | | return UX_IsLoggedIn(); |
| | | } |
| | | |
| | | std::string CUserManager2::getCurrentUserName() |
| | | { |
| | | std::string strName; |
| | | |
| | | int need = UX_GetCurrentUser(nullptr, 0); |
| | | std::wstring buf; buf.resize((size_t)need); |
| | | if (UX_GetCurrentUser(buf.data(), need) == UX_OK) { |
| | | if (!buf.empty() && buf.back() == L'\0') |
| | | buf.pop_back(); |
| | | |
| | | strName = CToolUnits::WStringToAnsi(buf); |
| | | } |
| | | |
| | | return strName; |
| | | } |
| | | |
| | | bool CUserManager2::IsAdminCurrent() |
| | | { |
| | | if (UX_IsLoggedIn() != 1) return false; |
| | | int need = UX_GetCurrentUser(nullptr, 0); if (need <= 0) return false; |
| | | std::wstring user; user.resize((size_t)need); |
| | | if (UX_GetCurrentUser(user.data(), need) != 0) return false; |
| | | if (!user.empty() && user.back() == L'\0') user.pop_back(); |
| | | int maxLvl = 0; auto rolesTxt = ReadBufferVia([](wchar_t* b, int n) { return UX_GetRoles(b, n); }); |
| | | for (auto& ln : SplitLines(rolesTxt)) { size_t p = ln.find(L':'); if (p != std::wstring::npos) { int lvl = _wtoi(ln.substr(p + 1).c_str()); if (lvl > maxLvl) maxLvl = lvl; } } |
| | | int myLvl = 0; auto usersTxt = ReadBufferVia([](wchar_t* b, int n) { return UX_GetUsers(b, n); }); |
| | | for (auto& ln : SplitLines(usersTxt)) { |
| | | if (ln.empty()) continue; size_t p1 = ln.find(L','), p2 = ln.find(L',', p1 == std::wstring::npos ? 0 : p1 + 1), p3 = ln.find(L',', p2 == std::wstring::npos ? 0 : p2 + 1); |
| | | std::wstring name = (p1 == std::wstring::npos ? ln : ln.substr(0, p1)); if (name == user) { if (p2 != std::wstring::npos) { std::wstring lvlS = ln.substr(p2 + 1, (p3 == std::wstring::npos ? ln.size() : p3) - (p2 + 1)); myLvl = _wtoi(lvlS.c_str()); } break; } |
| | | } |
| | | |
| | | return (maxLvl > 0) && (myLvl >= maxLvl); |
| | | } |
| | | |
| | | std::vector<CUserManager2::RoleInfo> CUserManager2::getRoles() |
| | | { |
| | | std::vector<RoleInfo> roles; |
| | | auto txt = ReadBufferVia([](wchar_t* b, int n) { return UX_GetRoles(b, n); }); |
| | | if (txt.empty()) { |
| | | return roles; |
| | | } |
| | | |
| | | for (auto& line : SplitLines(txt)) { |
| | | if (line.empty()) continue; |
| | | size_t pos = line.find(L':'); |
| | | RoleInfo info; |
| | | info.name = (pos == std::wstring::npos) ? line : line.substr(0, pos); |
| | | if (pos != std::wstring::npos) { |
| | | info.level = _wtoi(line.substr(pos + 1).c_str()); |
| | | } |
| | | |
| | | if (!info.name.empty()) { |
| | | roles.push_back(std::move(info)); |
| | | } |
| | | } |
| | | |
| | | std::sort(roles.begin(), roles.end(), [](const RoleInfo& a, const RoleInfo& b) { |
| | | if (a.level == b.level) { |
| | | return a.name < b.name; |
| | | } |
| | | return a.level > b.level; |
| | | }); |
| | | |
| | | return roles; |
| | | } |
| | | std::vector<CUserManager2::UserInfo> CUserManager2::getUsers() |
| | | { |
| | | std::vector<UserInfo> users; |
| | | auto txt = ReadBufferVia([](wchar_t* b, int n) { return UX_GetUsers(b, n); }); |
| | | if (txt.empty()) { |
| | | return users; |
| | | } |
| | | |
| | | std::map<int, std::wstring> roleMap; |
| | | for (auto& role : getRoles()) { |
| | | roleMap[role.level] = role.name; |
| | | } |
| | | |
| | | for (auto& line : SplitLines(txt)) { |
| | | if (line.empty()) continue; |
| | | auto parts = SplitByDelimiter(line, L','); |
| | | UserInfo info; |
| | | if (!parts.empty()) info.userName = parts[0]; |
| | | if (parts.size() > 1) info.displayName = parts[1]; |
| | | if (parts.size() > 2) info.roleLevel = _wtoi(parts[2].c_str()); |
| | | if (parts.size() > 3) info.enabled = (_wtoi(parts[3].c_str()) != 0); |
| | | auto it = roleMap.find(info.roleLevel); |
| | | if (it != roleMap.end()) { |
| | | info.roleName = it->second; |
| | | } |
| | | users.push_back(std::move(info)); |
| | | } |
| | | |
| | | return users; |
| | | } |
| | | |
| | | int CUserManager2::addUser(const std::wstring& userName, const std::wstring& displayName, |
| | | const std::wstring& password, const std::wstring& roleName, bool enabled) |
| | | { |
| | | int rc = UX_AddUser(userName.c_str(), displayName.c_str(), password.c_str(), roleName.c_str()); |
| | | if (rc == UX_OK && !enabled) { |
| | | UX_EnableUser(userName.c_str(), 0); |
| | | } |
| | | |
| | | return rc; |
| | | } |
| | | |
| | | int CUserManager2::updateUser(const std::wstring& userName, const std::wstring& displayName, |
| | | const std::wstring& password, const std::wstring& roleName, bool enabled) |
| | | { |
| | | const wchar_t* disp = displayName.empty() ? nullptr : displayName.c_str(); |
| | | const wchar_t* pwd = password.empty() ? nullptr : password.c_str(); |
| | | const wchar_t* role = roleName.empty() ? nullptr : roleName.c_str(); |
| | | return UX_UpdateUser(userName.c_str(), disp, pwd, role, enabled ? 1 : 0); |
| | | } |
| | | |
| | | int CUserManager2::deleteUser(const std::wstring& userName) |
| | | { |
| | | return UX_DeleteUser(userName.c_str()); |
| | | } |
| | | |
| | | int CUserManager2::setUserEnabled(const std::wstring& userName, bool enabled) |
| | | { |
| | | return UX_EnableUser(userName.c_str(), enabled ? 1 : 0); |
| | | } |
| | | |
| | | int CUserManager2::resetPassword(const std::wstring& userName, const std::wstring& password) |
| | | { |
| | | return UX_ResetPassword(userName.c_str(), password.c_str()); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | |
| | | #include <string> |
| | | #include <vector> |
| | | |
| | | class CUserManager2 |
| | | { |
| | | public: |
| | | static CUserManager2& getInstance(); |
| | | CUserManager2(const CUserManager2&) = delete; |
| | | CUserManager2& operator=(const CUserManager2&) = delete; |
| | | |
| | | struct RoleInfo |
| | | { |
| | | std::wstring name; |
| | | int level = 0; |
| | | }; |
| | | |
| | | struct UserInfo |
| | | { |
| | | std::wstring userName; |
| | | std::wstring displayName; |
| | | std::wstring roleName; |
| | | int roleLevel = 0; |
| | | bool enabled = false; |
| | | }; |
| | | |
| | | public: |
| | | void init(const char* pszDir); |
| | | bool login(const char* pszAccount, const char* pszPwd); |
| | | bool isLoggedIn(); |
| | | std::string getCurrentUserName(); |
| | | bool IsAdminCurrent(); |
| | | std::vector<RoleInfo> getRoles(); |
| | | std::vector<UserInfo> getUsers(); |
| | | int addUser(const std::wstring& userName, const std::wstring& displayName, |
| | | const std::wstring& password, const std::wstring& roleName, bool enabled); |
| | | int updateUser(const std::wstring& userName, const std::wstring& displayName, |
| | | const std::wstring& password, const std::wstring& roleName, bool enabled); |
| | | int deleteUser(const std::wstring& userName); |
| | | int setUserEnabled(const std::wstring& userName, bool enabled); |
| | | int resetPassword(const std::wstring& userName, const std::wstring& password); |
| | | |
| | | private: |
| | | CUserManager2(); |
| | | ~CUserManager2(); |
| | | }; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // CUserManager2Dlg.cpp |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "CUserManager2Dlg.h" |
| | | #include "afxdialogex.h" |
| | | #include "CUserEdit2Dlg.h" |
| | | #include "InputDialog.h" |
| | | #include "resource.h" |
| | | #include "ToolUnits.h" |
| | | |
| | | IMPLEMENT_DYNAMIC(CUserManager2Dlg, CDialogEx) |
| | | |
| | | CUserManager2Dlg::CUserManager2Dlg(CWnd* pParent) |
| | | : CDialogEx(IDD_DIALOG_USER_MANAGER2, pParent) |
| | | { |
| | | } |
| | | |
| | | CUserManager2Dlg::~CUserManager2Dlg() |
| | | { |
| | | } |
| | | |
| | | void CUserManager2Dlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_LIST1, m_listUsers); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CUserManager2Dlg, CDialogEx) |
| | | ON_WM_SIZE() |
| | | ON_BN_CLICKED(IDC_BUTTON_ADD, &CUserManager2Dlg::OnBnClickedButtonAdd) |
| | | ON_BN_CLICKED(IDC_BUTTON_EDIT, &CUserManager2Dlg::OnBnClickedButtonEdit) |
| | | ON_BN_CLICKED(IDC_BUTTON_DEL, &CUserManager2Dlg::OnBnClickedButtonDel) |
| | | ON_BN_CLICKED(IDC_BUTTON_RESET_PWD, &CUserManager2Dlg::OnBnClickedButtonResetPwd) |
| | | ON_BN_CLICKED(IDC_BUTTON_ENABLE, &CUserManager2Dlg::OnBnClickedButtonEnable) |
| | | ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CUserManager2Dlg::OnLvnItemchangedUsers) |
| | | END_MESSAGE_MAP() |
| | | |
| | | BOOL CUserManager2Dlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | InitList(); |
| | | RefreshUserList(); |
| | | UpdateButtonState(); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | } |
| | | |
| | | void CUserManager2Dlg::InitList() |
| | | { |
| | | DWORD dwStyle = m_listUsers.GetExtendedStyle(); |
| | | m_listUsers.SetExtendedStyle(dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); |
| | | m_listUsers.InsertColumn(0, _T("è´¦å·"), LVCFMT_LEFT, 90); |
| | | m_listUsers.InsertColumn(1, _T("æ¾ç¤ºå"), LVCFMT_LEFT, 100); |
| | | m_listUsers.InsertColumn(2, _T("è§è²"), LVCFMT_LEFT, 80); |
| | | m_listUsers.InsertColumn(3, _T("级å«"), LVCFMT_LEFT, 60); |
| | | m_listUsers.InsertColumn(4, _T("ç¶æ"), LVCFMT_LEFT, 70); |
| | | } |
| | | |
| | | void CUserManager2Dlg::RefreshUserList() |
| | | { |
| | | CString selectedName; |
| | | int currentIndex = GetSelectedIndex(); |
| | | if (currentIndex >= 0 && currentIndex < static_cast<int>(m_users.size())) { |
| | | selectedName = m_users[currentIndex].userName.c_str(); |
| | | } |
| | | |
| | | m_users = CUserManager2::getInstance().getUsers(); |
| | | m_listUsers.DeleteAllItems(); |
| | | |
| | | for (size_t i = 0; i < m_users.size(); ++i) { |
| | | const auto& user = m_users[i]; |
| | | CString account(user.userName.c_str()); |
| | | CString display(user.displayName.c_str()); |
| | | CString role(user.roleName.empty() ? L"-" : user.roleName.c_str()); |
| | | CString level; |
| | | level.Format(_T("%d"), user.roleLevel); |
| | | CString state = user.enabled ? _T("å¯ç¨") : _T("ç¦ç¨"); |
| | | |
| | | int row = m_listUsers.InsertItem(static_cast<int>(i), account); |
| | | m_listUsers.SetItemText(row, 1, display); |
| | | m_listUsers.SetItemText(row, 2, role); |
| | | m_listUsers.SetItemText(row, 3, level); |
| | | m_listUsers.SetItemText(row, 4, state); |
| | | } |
| | | |
| | | if (!selectedName.IsEmpty()) { |
| | | for (int i = 0; i < m_listUsers.GetItemCount(); ++i) { |
| | | if (selectedName.CompareNoCase(m_listUsers.GetItemText(i, 0)) == 0) { |
| | | m_listUsers.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED); |
| | | m_listUsers.EnsureVisible(i, FALSE); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | UpdateButtonState(); |
| | | } |
| | | |
| | | void CUserManager2Dlg::UpdateButtonState() |
| | | { |
| | | int index = GetSelectedIndex(); |
| | | BOOL hasSelection = (index >= 0); |
| | | |
| | | auto enable = [&](int id, BOOL enableFlag) { |
| | | if (CWnd* p = GetDlgItem(id)) { |
| | | p->EnableWindow(enableFlag); |
| | | } |
| | | }; |
| | | |
| | | enable(IDC_BUTTON_EDIT, hasSelection); |
| | | enable(IDC_BUTTON_DEL, hasSelection); |
| | | enable(IDC_BUTTON_RESET_PWD, hasSelection); |
| | | enable(IDC_BUTTON_ENABLE, hasSelection); |
| | | |
| | | CString toggleText = _T("ç¦ç¨/å¯ç¨"); |
| | | if (const auto* user = GetSelectedUser()) { |
| | | toggleText = user->enabled ? _T("ç¦ç¨") : _T("å¯ç¨"); |
| | | if (IsCurrentUser(*user)) { |
| | | enable(IDC_BUTTON_DEL, FALSE); |
| | | enable(IDC_BUTTON_ENABLE, FALSE); |
| | | } |
| | | } |
| | | |
| | | SetDlgItemText(IDC_BUTTON_ENABLE, toggleText); |
| | | } |
| | | |
| | | int CUserManager2Dlg::GetSelectedIndex() const |
| | | { |
| | | if (!::IsWindow(m_listUsers.GetSafeHwnd())) { |
| | | return -1; |
| | | } |
| | | return m_listUsers.GetNextItem(-1, LVNI_SELECTED); |
| | | } |
| | | |
| | | const CUserManager2::UserInfo* CUserManager2Dlg::GetSelectedUser() const |
| | | { |
| | | int index = GetSelectedIndex(); |
| | | if (index < 0 || index >= static_cast<int>(m_users.size())) { |
| | | return nullptr; |
| | | } |
| | | return &m_users[index]; |
| | | } |
| | | |
| | | std::wstring CUserManager2Dlg::ToWString(const CString& text) const |
| | | { |
| | | CString trimmed(text); |
| | | trimmed.Trim(); |
| | | |
| | | std::string str((LPTSTR)(LPCTSTR)trimmed); |
| | | return CToolUnits::AnsiToWString(str); |
| | | } |
| | | |
| | | void CUserManager2Dlg::ShowErrorMessage(const CString& action, int code) |
| | | { |
| | | const wchar_t* detail = UX_ErrorMessage(code); |
| | | CString msg; |
| | | msg.Format(_T("%s: %s"), action.GetString(), detail ? detail : L"Unknown"); |
| | | AfxMessageBox(msg, MB_ICONERROR); |
| | | } |
| | | |
| | | bool CUserManager2Dlg::IsCurrentUser(const CUserManager2::UserInfo& info) const |
| | | { |
| | | CString current(CUserManager2::getInstance().getCurrentUserName().c_str()); |
| | | CString account(info.userName.c_str()); |
| | | current.Trim(); |
| | | account.Trim(); |
| | | return !current.IsEmpty() && current.CompareNoCase(account) == 0; |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnBnClickedButtonAdd() |
| | | { |
| | | CUserEdit2Dlg dlg(false, this); |
| | | if (dlg.DoModal() != IDOK) { |
| | | return; |
| | | } |
| | | |
| | | CString account = dlg.m_strUsername; |
| | | account.Trim(); |
| | | CString display = dlg.m_strDisplayName; |
| | | display.Trim(); |
| | | if (display.IsEmpty()) { |
| | | display = account; |
| | | } |
| | | CString role = dlg.m_strRole; |
| | | role.Trim(); |
| | | CString password = dlg.m_strPassword; |
| | | password.Trim(); |
| | | |
| | | int rc = CUserManager2::getInstance().addUser(ToWString(account), ToWString(display), ToWString(password), ToWString(role), dlg.m_bEnabled == TRUE); |
| | | if (rc == UX_OK) { |
| | | RefreshUserList(); |
| | | AfxMessageBox(_T("æ°å¢ç¨æ·æå")); |
| | | } |
| | | else { |
| | | ShowErrorMessage(_T("æ°å¢ç¨æ·å¤±è´¥"), rc); |
| | | } |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnBnClickedButtonEdit() |
| | | { |
| | | const auto* user = GetSelectedUser(); |
| | | if (!user) { |
| | | AfxMessageBox(_T("è¯·éæ©ç¨æ·")); |
| | | return; |
| | | } |
| | | |
| | | CUserEdit2Dlg dlg(true, this); |
| | | dlg.m_strUsername = user->userName.c_str(); |
| | | dlg.m_strDisplayName = user->displayName.c_str(); |
| | | dlg.m_strRole = user->roleName.c_str(); |
| | | dlg.m_bEnabled = user->enabled ? TRUE : FALSE; |
| | | if (dlg.DoModal() != IDOK) { |
| | | return; |
| | | } |
| | | |
| | | CString display = dlg.m_strDisplayName; |
| | | display.Trim(); |
| | | CString password = dlg.m_strPassword; |
| | | password.Trim(); |
| | | CString role = dlg.m_strRole; |
| | | role.Trim(); |
| | | |
| | | int rc = CUserManager2::getInstance().updateUser(user->userName, ToWString(display), ToWString(password), ToWString(role), dlg.m_bEnabled == TRUE); |
| | | if (rc == UX_OK) { |
| | | RefreshUserList(); |
| | | AfxMessageBox(_T("ä¿åæå")); |
| | | } |
| | | else { |
| | | ShowErrorMessage(_T("ä¿å失败"), rc); |
| | | } |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnBnClickedButtonDel() |
| | | { |
| | | const auto* user = GetSelectedUser(); |
| | | if (!user) { |
| | | AfxMessageBox(_T("è¯·éæ©ç¨æ·")); |
| | | return; |
| | | } |
| | | |
| | | if (IsCurrentUser(*user)) { |
| | | AfxMessageBox(_T("ä¸è½å é¤å½åç»å½ç¨æ·")); |
| | | return; |
| | | } |
| | | |
| | | CString prompt; |
| | | prompt.Format(_T("ç¡®å®å é¤ç¨æ· %s ?"), CString(user->userName.c_str())); |
| | | if (AfxMessageBox(prompt, MB_ICONQUESTION | MB_YESNO) != IDYES) { |
| | | return; |
| | | } |
| | | |
| | | int rc = CUserManager2::getInstance().deleteUser(user->userName); |
| | | if (rc == UX_OK) { |
| | | RefreshUserList(); |
| | | AfxMessageBox(_T("å 餿å")); |
| | | } |
| | | else { |
| | | ShowErrorMessage(_T("å é¤å¤±è´¥"), rc); |
| | | } |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnBnClickedButtonResetPwd() |
| | | { |
| | | const auto* user = GetSelectedUser(); |
| | | if (!user) { |
| | | AfxMessageBox(_T("è¯·éæ©ç¨æ·")); |
| | | return; |
| | | } |
| | | |
| | | CInputDialog dlg(_T("éç½®å¯ç "), _T("请è¾å
¥æ°å¯ç :"), this); |
| | | if (dlg.DoModal() != IDOK) { |
| | | return; |
| | | } |
| | | |
| | | CString password = dlg.GetInputText(); |
| | | password.Trim(); |
| | | if (password.IsEmpty()) { |
| | | AfxMessageBox(_T("å¯ç ä¸è½ä¸ºç©º")); |
| | | return; |
| | | } |
| | | |
| | | int rc = CUserManager2::getInstance().resetPassword(user->userName, ToWString(password)); |
| | | if (rc == UX_OK) { |
| | | AfxMessageBox(_T("å¯ç å·²éç½®")); |
| | | } |
| | | else { |
| | | ShowErrorMessage(_T("é置失败"), rc); |
| | | } |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnBnClickedButtonEnable() |
| | | { |
| | | const auto* user = GetSelectedUser(); |
| | | if (!user) { |
| | | AfxMessageBox(_T("è¯·éæ©ç¨æ·")); |
| | | return; |
| | | } |
| | | |
| | | bool enable = !user->enabled; |
| | | int rc = CUserManager2::getInstance().setUserEnabled(user->userName, enable); |
| | | if (rc == UX_OK) { |
| | | RefreshUserList(); |
| | | CString msg = enable ? _T("ç¨æ·å·²å¯ç¨") : _T("ç¨æ·å·²ç¦ç¨"); |
| | | AfxMessageBox(msg); |
| | | } |
| | | else { |
| | | ShowErrorMessage(_T("æä½å¤±è´¥"), rc); |
| | | } |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnLvnItemchangedUsers(NMHDR* /*pNMHDR*/, LRESULT* pResult) |
| | | { |
| | | UpdateButtonState(); |
| | | *pResult = 0; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | |
| | | #include "CUserManager2.h" |
| | | #include <string> |
| | | #include <vector> |
| | | |
| | | class CUserManager2Dlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CUserManager2Dlg) |
| | | |
| | | public: |
| | | CUserManager2Dlg(CWnd* pParent = nullptr); |
| | | virtual ~CUserManager2Dlg(); |
| | | |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_USER_MANAGER2 }; |
| | | #endif |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnBnClickedButtonAdd(); |
| | | afx_msg void OnBnClickedButtonEdit(); |
| | | afx_msg void OnBnClickedButtonDel(); |
| | | afx_msg void OnBnClickedButtonResetPwd(); |
| | | afx_msg void OnBnClickedButtonEnable(); |
| | | afx_msg void OnLvnItemchangedUsers(NMHDR* pNMHDR, LRESULT* pResult); |
| | | |
| | | private: |
| | | CListCtrl m_listUsers; |
| | | std::vector<CUserManager2::UserInfo> m_users; |
| | | |
| | | void InitList(); |
| | | void RefreshUserList(); |
| | | void UpdateButtonState(); |
| | | int GetSelectedIndex() const; |
| | | const CUserManager2::UserInfo* GetSelectedUser() const; |
| | | std::wstring ToWString(const CString& text) const; |
| | | void ShowErrorMessage(const CString& action, int code); |
| | | bool IsCurrentUser(const CUserManager2::UserInfo& info) const; |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "CUserXLogDlg.h" |
| | | #include "afxdialogex.h" |
| | | #include <functional> |
| | | #include <vector> |
| | | #include <sstream> |
| | | |
| | | namespace |
| | | { |
| | | std::wstring ReadBufferVia(const std::function<int(wchar_t*, int)>& fn) |
| | | { |
| | | int need = fn(nullptr, 0); |
| | | if (need <= 0) { |
| | | return L""; |
| | | } |
| | | |
| | | std::wstring buffer; |
| | | buffer.resize(static_cast<size_t>(need)); |
| | | if (fn(buffer.data(), need) == UX_OK) { |
| | | if (!buffer.empty() && buffer.back() == L'\0') { |
| | | buffer.pop_back(); |
| | | } |
| | | return buffer; |
| | | } |
| | | |
| | | return L""; |
| | | } |
| | | |
| | | std::vector<std::wstring> SplitLines(const std::wstring& text) |
| | | { |
| | | std::vector<std::wstring> lines; |
| | | std::wstringstream ss(text); |
| | | std::wstring line; |
| | | while (std::getline(ss, line)) { |
| | | lines.push_back(line); |
| | | } |
| | | return lines; |
| | | } |
| | | } |
| | | |
| | | IMPLEMENT_DYNAMIC(CUserXLogDlg, CDialogEx) |
| | | |
| | | CUserXLogDlg::CUserXLogDlg(CWnd* pParent) |
| | | : CDialogEx(IDD_DIALOG_USERX_LOG, pParent) |
| | | { |
| | | } |
| | | |
| | | CUserXLogDlg::~CUserXLogDlg() |
| | | { |
| | | } |
| | | |
| | | void CUserXLogDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_LIST1, m_listLogs); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CUserXLogDlg, CDialogEx) |
| | | ON_WM_SIZE() |
| | | ON_WM_DESTROY() |
| | | END_MESSAGE_MAP() |
| | | |
| | | BOOL CUserXLogDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | InitListCtrl(); |
| | | RefreshLogs(); |
| | | AdjustLayout(); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CUserXLogDlg::InitListCtrl() |
| | | { |
| | | DWORD dwStyle = m_listLogs.GetExtendedStyle(); |
| | | m_listLogs.SetExtendedStyle(dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); |
| | | m_listLogs.InsertColumn(0, _T("æ¶é´"), LVCFMT_LEFT, 180); |
| | | m_listLogs.InsertColumn(1, _T("ç¨æ·"), LVCFMT_LEFT, 120); |
| | | m_listLogs.InsertColumn(2, _T("å¨ä½"), LVCFMT_LEFT, 120); |
| | | m_listLogs.InsertColumn(3, _T("æè¿°"), LVCFMT_LEFT, 200); |
| | | } |
| | | |
| | | void CUserXLogDlg::RefreshLogs() |
| | | { |
| | | m_logs.clear(); |
| | | m_listLogs.DeleteAllItems(); |
| | | |
| | | auto allLogs = ReadBufferVia([](wchar_t* buffer, int size) { |
| | | return UX_QueryLogs(200, buffer, size); |
| | | }); |
| | | |
| | | for (auto& rawLine : SplitLines(allLogs)) { |
| | | if (rawLine.empty()) continue; |
| | | |
| | | auto trim = [](std::wstring value) { |
| | | size_t first = value.find_first_not_of(L" \t\r\n"); |
| | | size_t last = value.find_last_not_of(L" \t\r\n"); |
| | | if (first == std::wstring::npos || last == std::wstring::npos) { |
| | | return std::wstring(); |
| | | } |
| | | return value.substr(first, last - first + 1); |
| | | }; |
| | | |
| | | auto takeField = [&](size_t& cursor) { |
| | | if (cursor == std::wstring::npos || cursor >= rawLine.length()) { |
| | | return std::wstring(); |
| | | } |
| | | size_t pos = rawLine.find(L',', cursor); |
| | | std::wstring part = (pos == std::wstring::npos) ? rawLine.substr(cursor) : rawLine.substr(cursor, pos - cursor); |
| | | cursor = (pos == std::wstring::npos) ? std::wstring::npos : pos + 1; |
| | | return trim(part); |
| | | }; |
| | | |
| | | size_t cursor = 0; |
| | | LogItem item; |
| | | item.time = takeField(cursor).c_str(); |
| | | item.user = takeField(cursor).c_str(); |
| | | item.action = takeField(cursor).c_str(); |
| | | if (cursor != std::wstring::npos && cursor < rawLine.length()) { |
| | | item.detail = trim(rawLine.substr(cursor)).c_str(); |
| | | } |
| | | |
| | | m_logs.push_back(item); |
| | | } |
| | | |
| | | for (size_t i = 0; i < m_logs.size(); ++i) { |
| | | const auto& log = m_logs[i]; |
| | | int row = m_listLogs.InsertItem(static_cast<int>(i), log.time); |
| | | m_listLogs.SetItemText(row, 1, log.user); |
| | | m_listLogs.SetItemText(row, 2, log.action); |
| | | m_listLogs.SetItemText(row, 3, log.detail); |
| | | } |
| | | } |
| | | |
| | | void CUserXLogDlg::AdjustLayout() |
| | | { |
| | | if (!::IsWindow(m_listLogs.GetSafeHwnd())) { |
| | | return; |
| | | } |
| | | |
| | | CRect rcClient; |
| | | GetClientRect(&rcClient); |
| | | const int margin = 7; |
| | | |
| | | CRect rcList(margin, margin, rcClient.right - margin, rcClient.bottom - 40); |
| | | m_listLogs.MoveWindow(rcList); |
| | | |
| | | auto moveButton = [&](int id, int order) { |
| | | if (CWnd* pBtn = GetDlgItem(id)) { |
| | | CRect rc; |
| | | pBtn->GetWindowRect(&rc); |
| | | ScreenToClient(&rc); |
| | | int width = rc.Width(); |
| | | int height = rc.Height(); |
| | | rc.left = rcClient.right - margin - width - order * (width + margin); |
| | | rc.right = rc.left + width; |
| | | rc.top = rcClient.bottom - margin - height; |
| | | rc.bottom = rc.top + height; |
| | | pBtn->MoveWindow(rc); |
| | | } |
| | | }; |
| | | |
| | | moveButton(IDOK, 1); |
| | | moveButton(IDCANCEL, 0); |
| | | } |
| | | |
| | | void CUserXLogDlg::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | AdjustLayout(); |
| | | } |
| | | |
| | | void CUserXLogDlg::OnDestroy() |
| | | { |
| | | CDialogEx::OnDestroy(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | |
| | | #include <vector> |
| | | #include <string> |
| | | |
| | | class CUserXLogDlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CUserXLogDlg) |
| | | |
| | | public: |
| | | CUserXLogDlg(CWnd* pParent = nullptr); |
| | | virtual ~CUserXLogDlg(); |
| | | |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_USERX_LOG }; |
| | | #endif |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnDestroy(); |
| | | |
| | | private: |
| | | struct LogItem |
| | | { |
| | | CString time; |
| | | CString user; |
| | | CString action; |
| | | CString detail; |
| | | }; |
| | | |
| | | CListCtrl m_listLogs; |
| | | std::vector<LogItem> m_logs; |
| | | |
| | | void InitListCtrl(); |
| | | void RefreshLogs(); |
| | | void AdjustLayout(); |
| | | }; |
| | |
| | | |
| | | |
| | | namespace SERVO { |
| | | // åéæ ¼å¼ |
| | | // åéç±»å |
| | | enum class SVFromat { |
| | | U1 = 0, |
| | | U2, |
| | |
| | | std::string getValue(); |
| | | __int64 getIntValue(); |
| | | std::vector<CVariable>& getVarsValue(); |
| | | void setName(const char* pszName) { m_strName = pszName; } |
| | | void setFormat(const char* pszFmt) { m_format = toFormat(pszFmt); } |
| | | void setRemark(const char* pszRemark) { m_strRemark = pszRemark; } |
| | | |
| | | private: |
| | | unsigned int m_nVarialbeId; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "CVariableEditDlg2.h" |
| | | #include "resource.h" |
| | | |
| | | IMPLEMENT_DYNAMIC(CVariableEditDlg2, CDialogEx) |
| | | |
| | | CVariableEditDlg2::CVariableEditDlg2(const CString& title, int varId, const CString& type, const CString& name, const CString& remark, CWnd* pParent) |
| | | : CDialogEx(IDD_DIALOG_VARIABLE_EDIT2, pParent), |
| | | m_strTitle(title), |
| | | m_varId(varId), |
| | | m_strType(type), |
| | | m_strName(name), |
| | | m_strRemark(remark) |
| | | { |
| | | } |
| | | |
| | | CVariableEditDlg2::~CVariableEditDlg2() |
| | | { |
| | | } |
| | | |
| | | void CVariableEditDlg2::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_EDIT_VAR_ID, m_editId); |
| | | DDX_Control(pDX, IDC_COMBO_VAR_TYPE, m_cbType); |
| | | DDX_Control(pDX, IDC_EDIT_VAR_NAME, m_editName); |
| | | DDX_Control(pDX, IDC_EDIT_VAR_REMARK, m_editRemark); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CVariableEditDlg2, CDialogEx) |
| | | END_MESSAGE_MAP() |
| | | |
| | | BOOL CVariableEditDlg2::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | SetWindowText(m_strTitle); |
| | | |
| | | CString strId; |
| | | strId.Format(_T("%d"), m_varId); |
| | | m_editId.SetWindowText(strId); |
| | | m_editId.SetReadOnly(TRUE); |
| | | |
| | | m_cbType.ResetContent(); |
| | | const TCHAR* fmts[] = { _T("U1"), _T("U2"), _T("I2"), _T("A20"), _T("A50"), _T("L") }; |
| | | for (auto f : fmts) { |
| | | m_cbType.AddString(f); |
| | | } |
| | | if (!m_strType.IsEmpty()) { |
| | | m_cbType.SelectString(-1, m_strType); |
| | | } |
| | | else { |
| | | m_cbType.SetCurSel(0); |
| | | } |
| | | |
| | | m_editName.SetWindowText(m_strName); |
| | | m_editRemark.SetWindowText(m_strRemark); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CVariableEditDlg2::OnOK() |
| | | { |
| | | CString name, fmt, remark; |
| | | m_editName.GetWindowText(name); |
| | | m_cbType.GetWindowText(fmt); |
| | | m_editRemark.GetWindowText(remark); |
| | | |
| | | fmt.MakeUpper(); |
| | | if (name.IsEmpty()) { |
| | | AfxMessageBox(_T("åç§°ä¸è½ä¸ºç©º")); |
| | | return; |
| | | } |
| | | if (fmt.IsEmpty()) { |
| | | AfxMessageBox(_T("ç±»åä¸è½ä¸ºç©º")); |
| | | return; |
| | | } |
| | | if (fmt != _T("U1") && fmt != _T("U2") && fmt != _T("I2") |
| | | && fmt != _T("A20") && fmt != _T("A50") && fmt != _T("L")) { |
| | | AfxMessageBox(_T("ç±»åå¿
é¡»æ¯ U1/U2/I2/A20/A50/L")); |
| | | return; |
| | | } |
| | | |
| | | m_strName = name; |
| | | m_strType = fmt; |
| | | m_strRemark = remark; |
| | | |
| | | CDialogEx::OnOK(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | |
| | | // åéç¼è¾å¯¹è¯æ¡ï¼æ°å¢/ç¼è¾å
±ç¨ï¼ä½¿ç¨èµæºæ¨¡æ¿ï¼ |
| | | class CVariableEditDlg2 : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CVariableEditDlg2) |
| | | |
| | | public: |
| | | CVariableEditDlg2(const CString& title, int varId, const CString& type, const CString& name, const CString& remark, CWnd* pParent = nullptr); |
| | | virtual ~CVariableEditDlg2(); |
| | | |
| | | int GetVarId() const { return m_varId; } |
| | | CString GetTypeText() const { return m_strType; } |
| | | CString GetNameText() const { return m_strName; } |
| | | CString GetRemark() const { return m_strRemark; } |
| | | |
| | | protected: |
| | | virtual BOOL OnInitDialog() override; |
| | | virtual void DoDataExchange(CDataExchange* pDX) override; |
| | | afx_msg void OnOK(); |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | |
| | | private: |
| | | CString m_strTitle; |
| | | int m_varId; |
| | | CString m_strType; |
| | | CString m_strName; |
| | | CString m_strRemark; |
| | | |
| | | CEdit m_editId, m_editName, m_editRemark; |
| | | CComboBox m_cbType; |
| | | }; |
| | |
| | | { |
| | | const ClientInfo& client = clients[i]; |
| | | |
| | | int nItem = m_listClients.InsertItem(i, CString(client.ip.c_str())); |
| | | int nItem = m_listClients.InsertItem((int)i, CString(client.ip.c_str())); |
| | | m_listClients.SetItemText(nItem, 1, CString(std::to_string(client.port).c_str())); |
| | | m_listClients.SetItemText(nItem, 2, client.versionOk ? _T("æ£å¸¸") : _T("å¼å¸¸")); |
| | | m_listClients.SetItemText(nItem, 3, CString(client.status.c_str())); |
| | |
| | | #define RX_CODE_MASTER_STATE_CHANGED 1011 |
| | | #define RX_CODE_EQ_ROBOT_TASK 1012 |
| | | #define RX_CODE_LOADPORT_STATUS_CHANGED 1014 |
| | | #define RX_CODE_CONTROL_STATE_CHANGED 1015 |
| | | #define RX_CODE_CONTROLJOB_CHANGED 1016 |
| | | |
| | | /* 软件侧 ALID */ |
| | | #define ALID_SOFTWARE_PAUSE_EVENT 9000 |
| | | #define ALID_SOFTWARE_TEST_ALARM 9099 |
| | | |
| | | /* Channel Name */ |
| | | #define MC_CHANNEL1_NAME "McChannel1" |
| | |
| | | #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) |
| | |
| | | |
| | | /* PPIDååæå¤§é¿åº¦ */ |
| | | #define PPID_NAME_MAX 80 |
| | | |
| | | |
| | | /* è§£é¤è¦å æé® */ |
| | | #define BTN_ALARM_OFF_FRAME_NORMAL RGB(88, 88, 88) |
| | | #define BTN_ALARM_OFF_FRAME_HOVER RGB(88, 88, 88) |
| | | #define BTN_ALARM_OFF_FRAME_PRESS RGB(88, 88, 88) |
| | | #define BTN_ALARM_OFF_BKGND_NORMAL RGB(255, 127, 39) |
| | | #define BTN_ALARM_OFF_BKGND_HOVER RGB(255, 157, 59) |
| | | #define BTN_ALARM_OFF_BKGND_PRESS RGB(255, 100, 29) |
| | | |
| | | /* éé³æé® */ |
| | | #define BTN_SOUND_OFF_FRAME_NORMAL RGB(88, 88, 88) |
| | | #define BTN_SOUND_OFF_FRAME_HOVER RGB(88, 88, 88) |
| | | #define BTN_SOUND_OFF_FRAME_PRESS RGB(88, 88, 88) |
| | | #define BTN_SOUND_OFF_BKGND_NORMAL RGB(255, 127, 39) |
| | | #define BTN_SOUND_OFF_BKGND_HOVER RGB(255, 157, 59) |
| | | #define BTN_SOUND_OFF_BKGND_PRESS RGB(255, 100, 29) |
| | | #define BTN_SOUND_ON_BKGND_NORMAL RGB(100, 200, 100) |
| | | #define BTN_SOUND_ON_BKGND_HOVER RGB(150, 250, 150) |
| | | #define BTN_SOUND_ON_BKGND_PRESS RGB(50, 150, 50) |
| | | |
| | |
| | | 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; |
| | | } |
| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "EqsGraphWnd.h" |
| | | #include "ColorTransfer.h" |
| | | #include "MapPosWnd.h" |
| | |
| | | m_nMagneticLinHoz = 0; |
| | | m_nMagneticLinVer = 0; |
| | | m_hFontTitle = nullptr; |
| | | m_nIndicatorSize = 10; |
| | | m_nIndicatorMargin = 3; |
| | | |
| | | } |
| | | |
| | |
| | | wc.cbClsExtra = 0; |
| | | wc.cbWndExtra = 0; |
| | | |
| | | // 注åçªå£ç±» |
| | | // 注åçªå£ç±» |
| | | return (::RegisterClass(&wc) != 0); |
| | | } |
| | | |
| | |
| | | |
| | | m_crItemIdText[0] = CColorTransfer::ApproximateColor(m_crItemNameText[0], -0.3f); |
| | | m_crItemIdText[1] = CColorTransfer::ApproximateColor(m_crItemNameText[1], -0.3f); |
| | | } |
| | | |
| | | void CEqsGraphWnd::SetIndicatorSize(int nSize) |
| | | { |
| | | if (nSize > 0) { |
| | | m_nIndicatorSize = nSize; |
| | | } |
| | | } |
| | | |
| | | void CEqsGraphWnd::SetIndicatorMargin(int nMargin) |
| | | { |
| | | if (nMargin >= 0) { |
| | | m_nIndicatorMargin = nMargin; |
| | | } |
| | | } |
| | | |
| | | void CEqsGraphWnd::EnableScroll(BOOL bEnable) |
| | |
| | | } |
| | | |
| | | /* |
| | | * 计ç®ç£å线ä½ç½® |
| | | * 计ç®ç£å线ä½ç½® |
| | | */ |
| | | void CEqsGraphWnd::CalculateMagneticLine(EQITEM* pItem, LPRECT lprcItemRect, int &hoz, int &ver) |
| | | { |
| | |
| | | ver = 0; |
| | | #define MAGNETIC_DIS 10 |
| | | |
| | | // æ£æµæ¯å¦æ¥è¿æå¯¹é½ |
| | | // æ£æµæ¯å¦æ¥è¿æå¯¹é½ |
| | | for (int i = 0; i < m_arItem.GetSize(); i++) { |
| | | EQITEM *pTemp = (EQITEM*)m_arItem.GetAt(i); |
| | | if (pTemp != pItem) { |
| | |
| | | } |
| | | |
| | | /* |
| | | * åå¾In Pinçåºå |
| | | * åå¾In Pinçåºå |
| | | * pItem -- EQITEM |
| | | * lpRect -- å¾å°çRect |
| | | * è¿åæ¯å¦æå |
| | | * lpRect -- å¾å°çRect |
| | | * è¿åæ¯å¦æå |
| | | */ |
| | | BOOL CEqsGraphWnd::GetItemRect(EQITEM* pItem, LPRECT lpRect) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * åå¾In Pinçåºå |
| | | * åå¾In Pinçåºå |
| | | * pItem -- EQITEM |
| | | * nPinIndex -- in pinç´¢å¼ |
| | | * lpRect -- å¾å°çRect |
| | | * è¿åæ¯å¦æå |
| | | * nPinIndex -- in pinç´¢å¼ |
| | | * lpRect -- å¾å°çRect |
| | | * è¿åæ¯å¦æå |
| | | */ |
| | | BOOL CEqsGraphWnd::GetInPinRect(EQITEM* pItem, int nPinIndex, LPRECT lpRect) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * åå¾Out Pinçåºå |
| | | * åå¾Out Pinçåºå |
| | | * pItem -- EQITEM |
| | | * nPinIndex -- in pinç´¢å¼ |
| | | * lpRect -- å¾å°çRect |
| | | * è¿åæ¯å¦æå |
| | | * nPinIndex -- in pinç´¢å¼ |
| | | * lpRect -- å¾å°çRect |
| | | * è¿åæ¯å¦æå |
| | | */ |
| | | BOOL CEqsGraphWnd::GetOutPinRect(EQITEM* pItem, int nPinIndex, LPRECT lpRect) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * åå¾PinçPoint |
| | | * åå¾PinçPoint |
| | | * pItem -- EQITEM |
| | | * nPinIndex -- in pinç´¢å¼ |
| | | * lpRect -- å¾å°çRect |
| | | * è¿åæ¯å¦æå |
| | | * nPinIndex -- in pinç´¢å¼ |
| | | * lpRect -- å¾å°çRect |
| | | * è¿åæ¯å¦æå |
| | | */ |
| | | BOOL CEqsGraphWnd::GetPinPoint(PIN *pPin, LPPOINT lpPoint) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * æ¸
空PINè¿æ¥çº¿ç¼åç¹ï¼ä»¥ä¾¿éæ°è®¡ç®åç»å¶ |
| | | * æ¸
空PINè¿æ¥çº¿ç¼åç¹ï¼ä»¥ä¾¿éæ°è®¡ç®åç»å¶ |
| | | */ |
| | | void CEqsGraphWnd::ClearConnectedLinePoint(EQITEM*& pItem) |
| | | { |
| | |
| | | |
| | | void CEqsGraphWnd::SetOnListener(EqsGraphListener& listener) |
| | | { |
| | | m_listener.onConnectPin = listener.onConnectPin; |
| | | m_listener.onCheckConnectPin = listener.onCheckConnectPin; |
| | | m_listener.onDisconnectPin = listener.onDisconnectPin; |
| | | m_listener.onDeleteEqItem = listener.onDeleteEqItem; |
| | | m_listener.onEqItemPosChanged = listener.onEqItemPosChanged; |
| | | m_listener.onDblckEqItem = listener.onDblckEqItem; |
| | | m_listener.onRclickEqItem = listener.onRclickEqItem; |
| | | m_listener.onSelectEqItem = listener.onSelectEqItem; |
| | | m_listener = listener; |
| | | } |
| | | |
| | | BOOL CEqsGraphWnd::SetCurSel(int nSel) |
| | |
| | | */ |
| | | EQITEM* CEqsGraphWnd::AddItem(int id, CString strText, DWORD_PTR dwData, int nType/* = ITEM_NORMAL*/) |
| | | { |
| | | // éè¦è®¡ç®ä¸ä¸ªæ°ä½ç½®ï¼ä¸ç¶å
¨é¨éå å¨ä¸èµ· |
| | | // éè¦è®¡ç®ä¸ä¸ªæ°ä½ç½®ï¼ä¸ç¶å
¨é¨éå å¨ä¸èµ· |
| | | int x, y; |
| | | x = (m_arItem.GetCount() % 4) * 218; |
| | | y = (m_arItem.GetCount() / 4) * 168; |
| | |
| | | return 0; |
| | | } |
| | | |
| | | // å é¤Item, 妿pinæè¿æ¥ï¼æ³¨æå
æå¼ |
| | | // å é¤Item, 妿pinæè¿æ¥ï¼æ³¨æå
æå¼ |
| | | int CEqsGraphWnd::DeleteItem(EQITEM* pItem) |
| | | { |
| | | for (int i = 0; i < m_arItem.GetSize(); i++) { |
| | |
| | | } |
| | | |
| | | /* |
| | | * 设置å项çéä¸ç¶æ |
| | | * 设置å项çéä¸ç¶æ |
| | | */ |
| | | void CEqsGraphWnd::SetItemSelectState(int nIndex, BOOL bSelect) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * æ£æµåæ ç¹æå¨ç项 |
| | | * è¿å项类å, å¦HT_ITEM, HT_PIN, HT_LINE |
| | | * pItem - æå¨çEQITEM |
| | | * pPin --æå¨çpin, 妿å¨è¿çº¿ä¸ï¼è¡¨ç¤ºæå±pin, out pinï¼ |
| | | * æ£æµåæ ç¹æå¨ç项 |
| | | * è¿å项类å, å¦HT_ITEM, HT_PIN, HT_LINE |
| | | * pItem - æå¨çEQITEM |
| | | * pPin --æå¨çpin, 妿å¨è¿çº¿ä¸ï¼è¡¨ç¤ºæå±pin, out pinï¼ |
| | | */ |
| | | int CEqsGraphWnd::HighTest(POINT pt, OUT EQITEM*& pItem, OUT PIN *& pPin) |
| | | { |
| | | // æ£æµæ¯å¦å¨æä¸ªå项 |
| | | // æ£æµæ¯å¦å¨æä¸ªå项 |
| | | int nRet = HT_NOWHERE; |
| | | pItem = NULL; |
| | | pPin = NULL; |
| | |
| | | EQITEM *pTempItem = (EQITEM*)m_arItem.GetAt(i); |
| | | GetItemRect(pTempItem, &rcItem); |
| | | if (::PtInRect(&rcItem, pt)) { |
| | | // å¨Item |
| | | // å¨Item |
| | | pItem = pTempItem; |
| | | nRet = HT_ITEM; |
| | | break; |
| | |
| | | CPtrArray * pPins = (CPtrArray *)pTempItem->pInPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | if (GetInPinRect(pTempItem, j, &rcPin) && ::PtInRect(&rcPin, pt)) { |
| | | // å¨in pinä¸ |
| | | // å¨in pinä¸ |
| | | pPin = (PIN *)pPins->GetAt(j); |
| | | pItem = pTempItem; |
| | | nRet = HT_PIN; |
| | |
| | | pPins = (CPtrArray *)pTempItem->pOutPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | if (GetOutPinRect(pTempItem, j, &rcPin) && ::PtInRect(&rcPin, pt)) { |
| | | // å¨out pin |
| | | // å¨out pin |
| | | pPin = (PIN *)pPins->GetAt(j); |
| | | pItem = pTempItem; |
| | | nRet = HT_PIN; |
| | | break; |
| | | } |
| | | else { |
| | | // æ¯å¦å¨pinè¿æ¥çº¿ä¸,å³å¤æç¹æ¯å¦å¨çº¿ä¸ |
| | | // ç¹å°ç´çº¿çè·ç¦»å
¬å¼ï¼å
éè¿p1,p2ç¨ä¸¤ç¹å¼æ±åºç´çº¿ç表达å¼ï¼åå¥è·ç¦»å
¬å¼ï¼ï¼abs()为åç»å¯¹å¼å½æ°ï¼sqrt()ä¸ºå¼æ ¹å·å½æ° |
| | | // æ¯å¦å¨pinè¿æ¥çº¿ä¸,å³å¤æç¹æ¯å¦å¨çº¿ä¸ |
| | | // ç¹å°ç´çº¿çè·ç¦»å
¬å¼ï¼å
éè¿p1,p2ç¨ä¸¤ç¹å¼æ±åºç´çº¿ç表达å¼ï¼åå¥è·ç¦»å
¬å¼ï¼ï¼abs()为åç»å¯¹å¼å½æ°ï¼sqrt()ä¸ºå¼æ ¹å·å½æ° |
| | | PIN *pTempPin = (PIN *)pPins->GetAt(j); |
| | | if (pTempPin->pConnectedPin != NULL && pTempPin->nLinePtCount > 1) { |
| | | for (int i = 0; i < pTempPin->nLinePtCount - 1; i++) { |
| | |
| | | } |
| | | |
| | | /* |
| | | * ç»å¶è线æ¡ï¼ä»£è¡¨æ£å¨æå¨çitem |
| | | * ç»å¶è线æ¡ï¼ä»£è¡¨æ£å¨æå¨çitem |
| | | */ |
| | | void CEqsGraphWnd::DrawDropItemRectangle(LPRECT lpRect1, LPRECT lpRect2) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * ç»å¶ç£å¸çº¿ |
| | | * ç»å¶ç£å¸çº¿ |
| | | */ |
| | | void CEqsGraphWnd::DrawMagneticLine(LPRECT lprcClient, int nHozLine1, int nHozLine2, int nVerLine1, int nVerLine2) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * ç¼å¶Pinè¿æ¥çº¿ |
| | | * pBrush -- ç»å· |
| | | * pPen - ç»ç¬ |
| | | * lpPt1, lpPt2 -- Pinèçä½ç½® |
| | | * lpRect1, lpRect2 -- 两个ItemçRect |
| | | * ç¼å¶Pinè¿æ¥çº¿ |
| | | * pBrush -- ç»å· |
| | | * pPen - ç»ç¬ |
| | | * lpPt1, lpPt2 -- Pinèçä½ç½® |
| | | * lpRect1, lpRect2 -- 两个ItemçRect |
| | | */ |
| | | void CEqsGraphWnd::DrawPinConnectedLine(Gdiplus::Graphics *pGraphics, Gdiplus::Brush *pBrush, Gdiplus::Pen *pPen, LPPOINT lpPt1, LPPOINT lpPt2, |
| | | LPRECT lpRect1, LPRECT lpRect2, PIN *pOwnerPin) |
| | | { |
| | | // å¦ææ²¡æç¼å线æ¡çPOINTï¼åå
计ç®å¹¶ç¼å |
| | | // å¦ææ²¡æç¼å线æ¡çPOINTï¼åå
计ç®å¹¶ç¼å |
| | | ASSERT(pOwnerPin); |
| | | |
| | | int nPinCount = ((CPtrArray*)pOwnerPin->pItem->pOutPins)->GetSize(); |
| | |
| | | int nMargin = 12; |
| | | int x1, x2, y1; |
| | | |
| | | if (pOwnerPin->nLinePtCount == 0) { // 第ä¸ä¸ªç¹çæå°æçº¿é¿ |
| | | if (pOwnerPin->nLinePtCount == 0) { // 第ä¸ä¸ªç¹çæå°æçº¿é¿ |
| | | ::OffsetRect(lpRect1, +m_nOffsetX, +m_nOffsetY); |
| | | ::OffsetRect(lpRect2, +m_nOffsetX, +m_nOffsetY); |
| | | lpPt1->x += m_nOffsetX; // æ¶é¤åç§» |
| | | lpPt1->x += m_nOffsetX; // æ¶é¤åç§» |
| | | lpPt1->y += m_nOffsetY; |
| | | lpPt2->x += m_nOffsetX; |
| | | lpPt2->y += m_nOffsetY; |
| | |
| | | } |
| | | |
| | | /* |
| | | * WindowProcï¼çªå£è¿ç¨ |
| | | * WindowProcï¼çªå£è¿ç¨ |
| | | */ |
| | | LRESULT CALLBACK CEqsGraphWnd::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | } |
| | | |
| | | |
| | | // å¤ççªå£æ¶æ¯ |
| | | // å¤ççªå£æ¶æ¯ |
| | | ASSERT(hWnd); |
| | | switch (uMsg) |
| | | { |
| | |
| | | |
| | | /* |
| | | * WM_NCCREATE |
| | | * çªå£å建 |
| | | * çªå£å建 |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | |
| | | /* |
| | | * WM_DESTROY |
| | | * çªå£éæ¯ |
| | | * çªå£éæ¯ |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnDestroy(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | |
| | | /* |
| | | * WM_MOUSEMOVE |
| | | * é¼ æ æ»å¨ |
| | | * é¼ æ æ»å¨ |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnMouseMove(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | |
| | | /* |
| | | * WM_LBUTTONDOWN |
| | | * é¼ æ å·¦é®æä¸ |
| | | * é¼ æ å·¦é®æä¸ |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | int nLastVerLine = 0; |
| | | |
| | | |
| | | // æ£æµç¹å»åæ æ¯å¦å¨æä¸å项ä¸ï¼å¦æ¯ï¼åé«äº®æ¾ç¤º |
| | | // æ£æµç¹å»åæ æ¯å¦å¨æä¸å项ä¸ï¼å¦æ¯ï¼åé«äº®æ¾ç¤º |
| | | EQITEM* pLastItem = m_pCurItem; |
| | | PIN *pLastPin = m_pCurPin; |
| | | PIN *pLastSelLineOutPin = m_pSelLineOutPin; |
| | |
| | | bChanged = pLastItem != m_pCurItem || pLastPin != m_pCurPin || pLastSelLineOutPin != m_pSelLineOutPin; |
| | | |
| | | |
| | | // å·æ° |
| | | // å·æ° |
| | | SetFocus(m_hWnd); |
| | | if (bChanged) { |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | |
| | | |
| | | // ææé¼ æ æ¶æ¯ï¼æ£æµæ¯å¦æå¨ |
| | | // ææé¼ æ æ¶æ¯ï¼æ£æµæ¯å¦æå¨ |
| | | if (nRet == HT_ITEM && m_pCurItem != NULL) { |
| | | GetItemRect(m_pCurItem, &rcItem); |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | // ææé¼ æ æ¶æ¯ï¼æ£æµæ¯å¦è¿æ¥å¼è |
| | | // ææé¼ æ æ¶æ¯ï¼æ£æµæ¯å¦è¿æ¥å¼è |
| | | else if (nRet == HT_PIN && m_pCurPin != NULL) { |
| | | if (::GetCapture() == NULL) { |
| | | BOOL bLast = FALSE; |
| | |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | |
| | | // æ¦é¤ä¸ä¸æ¬¡ |
| | | // æ¦é¤ä¸ä¸æ¬¡ |
| | | if (bLast) { |
| | | DrawPinWillConnectLine(lineColor, &ptPin, &ptLast); |
| | | } |
| | | |
| | | // æ£æµæ¯å¦å¯ä»¥è¿æ¥ |
| | | // æ£æµæ¯å¦å¯ä»¥è¿æ¥ |
| | | bCanConnect = false; |
| | | nRet = HighTest(ptNew, pHitItem, pHitPin); |
| | | if (nRet == HT_PIN) { |
| | |
| | | ptNew = msg.pt; |
| | | ::ScreenToClient(m_hWnd, &ptNew); |
| | | |
| | | // æ¦é¤ä¸ä¸æ¬¡ |
| | | // æ¦é¤ä¸ä¸æ¬¡ |
| | | if (bLast) { |
| | | DrawPinWillConnectLine(lineColor, &ptPin, &ptLast); |
| | | } |
| | | |
| | | // æ£æµæ¯å¦å¯ä»¥è¿æ¥ |
| | | // æ£æµæ¯å¦å¯ä»¥è¿æ¥ |
| | | bCanConnect = false; |
| | | nRet = HighTest(ptNew, pHitItem, pHitPin); |
| | | if (nRet == HT_PIN) { |
| | |
| | | } |
| | | |
| | | |
| | | // æ£æµé¼ æ æ¶æ¯ï¼æ£æµæ¯å¦ç§»å¨ç»å¸ |
| | | // æ£æµé¼ æ æ¶æ¯ï¼æ£æµæ¯å¦ç§»å¨ç»å¸ |
| | | else if (nRet == HT_NOWHERE) { |
| | | if (::GetCapture() == NULL) { |
| | | int nLastOffsetX = m_nOffsetX; |
| | |
| | | |
| | | /* |
| | | * WM_LBUTTONDBLCLK |
| | | * é¼ æ å·¦é®åå» |
| | | * é¼ æ å·¦é®åå» |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnLButtonDblclk(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | rcLast = { 0, 0, 0, 0 }; |
| | | |
| | | // æ£æµç¹å»åæ æ¯å¦å¨æä¸å项ä¸ï¼å¦æ¯ï¼åé«äº®æ¾ç¤º |
| | | // æ£æµç¹å»åæ æ¯å¦å¨æä¸å项ä¸ï¼å¦æ¯ï¼åé«äº®æ¾ç¤º |
| | | EQITEM* pLastItem = m_pCurItem; |
| | | BOOL bChanged = FALSE; |
| | | EQITEM* pHitItem = NULL; |
| | |
| | | |
| | | /* |
| | | * WM_MOUSEWHEEL |
| | | * é¼ æ æ»å¨ |
| | | * é¼ æ æ»å¨ |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnMouseWheel(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | |
| | | /* |
| | | * WM_MOUSEHWHEEL |
| | | * é¼ æ æ»å¨ |
| | | * é¼ æ æ»å¨ |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnMouseHWheel(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | |
| | | /* |
| | | * WM_RBUTTONDOWN |
| | | * é¼ æ å·¦é®æä¸ |
| | | * é¼ æ å·¦é®æä¸ |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnRButtonDown(WPARAM wParam, LPARAM lParam) |
| | | { |
| | |
| | | GetClientRect(m_hWnd, &rcClient); |
| | | rcLast = { 0, 0, 0, 0 }; |
| | | |
| | | // æ£æµç¹å»åæ æ¯å¦å¨æä¸å项ä¸ï¼å¦æ¯ï¼åé«äº®æ¾ç¤º |
| | | // æ£æµç¹å»åæ æ¯å¦å¨æä¸å项ä¸ï¼å¦æ¯ï¼åé«äº®æ¾ç¤º |
| | | EQITEM* pLastItem = m_pCurItem; |
| | | PIN *pLastPin = m_pCurPin; |
| | | PIN *pLastSelLineOutPin = m_pSelLineOutPin; |
| | |
| | | bChanged = pLastItem != m_pCurItem || pLastPin != m_pCurPin || pLastSelLineOutPin != m_pSelLineOutPin; |
| | | |
| | | |
| | | // å·æ° |
| | | // å·æ° |
| | | SetFocus(m_hWnd); |
| | | if (bChanged) { |
| | | ::InvalidateRect(m_hWnd, &rcClient, TRUE); |
| | | } |
| | | |
| | | |
| | | // ææé¼ æ æ¶æ¯ï¼æ£æµæ¯å¦æå¨ |
| | | // ææé¼ æ æ¶æ¯ï¼æ£æµæ¯å¦æå¨ |
| | | if (nRet == HT_ITEM && m_pCurItem != NULL) { |
| | | CopyRect(&rcItem, &m_pCurItem->rect); |
| | | |
| | |
| | | |
| | | /* |
| | | * WM_KEYDOWN |
| | | * é®çæ¶æ¯ï¼æä¸æé® |
| | | * é®çæ¶æ¯ï¼æä¸æé® |
| | | */ |
| | | LRESULT CEqsGraphWnd::OnKeyDown(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | BOOL bChanged = FALSE; |
| | | if (wParam == VK_DELETE) { |
| | | // 妿å½åéæ©ä¸ºçº¿ï¼åæå¼è¿æ¥ |
| | | // 妿å½åéæ©ä¸ºçº¿ï¼åæå¼è¿æ¥ |
| | | if (m_pSelLineOutPin != NULL) { |
| | | if (m_listener.onDisconnectPin != nullptr) { |
| | | if (m_listener.onDisconnectPin(m_pSelLineOutPin)) { |
| | |
| | | CString strText; |
| | | HBRUSH hBrushBK; |
| | | |
| | | |
| | | // BeginPaint |
| | | PAINTSTRUCT ps; |
| | | hDC = BeginPaint(m_hWnd, &ps); |
| | |
| | | rcClient.bottom - rcClient.top); |
| | | ::SelectObject(hMemDC, hBitmap); |
| | | |
| | | |
| | | // èæ¯é¢è² |
| | | // èæ¯é¢è² |
| | | hBrushBK = CreateSolidBrush(m_crBkgnd); |
| | | ::FillRect(hMemDC, &rcClient, hBrushBK); |
| | | DeleteObject(hBrushBK); |
| | | |
| | | |
| | | // æ é¢ |
| | | // æ é¢åä½ |
| | | if (m_hFontTitle == nullptr) { |
| | | LOGFONT lf; |
| | | HFONT hFontDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT); |
| | |
| | | m_hFontTitle = CreateFontIndirect(&lf); |
| | | } |
| | | |
| | | // ç»å¶æ é¢ææ¬ |
| | | { |
| | | char szTitle[256]; |
| | | char szTitle[256] = { 0 }; |
| | | GetWindowText(m_hWnd, szTitle, 256); |
| | | RECT rcTitle; |
| | | rcTitle.left = rcClient.left + 5; |
| | |
| | | ::DrawText(hMemDC, szTitle, (int)strlen(szTitle), &rcTitle, DT_LEFT | DT_TOP); |
| | | } |
| | | |
| | | |
| | | // ç»å¶å项 |
| | | // ç»å¶å项 |
| | | HBRUSH hbrItemBackground[2]; |
| | | HBRUSH hbrItemFrame[2]; |
| | | HBRUSH hbrPinBackground[3]; |
| | | HBRUSH hbrIndicator; |
| | | HBRUSH hbrIndicatorGray; |
| | | |
| | | hbrItemBackground[0] = CreateSolidBrush(m_crItemBackground[0]); |
| | | hbrItemBackground[1] = CreateSolidBrush(m_crItemBackground[1]); |
| | | hbrItemFrame[0] = CreateSolidBrush(m_crItemFrame[0]); |
| | | hbrItemFrame[1] = CreateSolidBrush(m_crItemFrame[1]); |
| | | hbrIndicator = CreateSolidBrush(RGB(34, 177, 76)); |
| | | hbrIndicator = CreateSolidBrush(RGB(34, 177, 76)); // ç»¿è² |
| | | hbrIndicatorGray = CreateSolidBrush(RGB(192, 192, 192)); // ç°è² |
| | | |
| | | for (int i = 0; i < 3; i++) { |
| | | hbrPinBackground[i] = CreateSolidBrush(m_crPinBkgnd[i]); |
| | | } |
| | | |
| | | |
| | | // gdi+ |
| | | Gdiplus::Graphics graphics(hMemDC); |
| | |
| | | graphics.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); |
| | | } |
| | | |
| | | |
| | | SetBkMode(hMemDC, TRANSPARENT); |
| | | { |
| | | RECT rcItem; |
| | | int nPinState; |
| | | int nItemCount = (int)m_arItem.GetCount(); |
| | | |
| | | // å
ç» itemãææ¬ãpin åæç¤ºç¯ |
| | | for (int i = 0; i < nItemCount; i++) { |
| | | EQITEM* pItem = (EQITEM*)m_arItem.GetAt(i); |
| | | if (pItem->nFlashFlag == 1) { |
| | | continue; |
| | | } |
| | | |
| | | GetItemRect(pItem, &rcItem); |
| | | |
| | | |
| | | // åé¡¹èæ¯åè¾¹æ¡ |
| | | // åé¡¹èæ¯åè¾¹æ¡ |
| | | if (m_nItemRound == 0) { |
| | | ::FillRect(hMemDC, &rcItem, pItem->bHighlight ? hbrItemBackground[1] : hbrItemBackground[0]); |
| | | ::FrameRect(hMemDC, &rcItem, pItem->bHighlight ? hbrItemFrame[1] : hbrItemFrame[0]); |
| | |
| | | ::DeleteObject(hRgn); |
| | | } |
| | | |
| | | |
| | | // nameåid |
| | | // name |
| | | HFONT hFontOld = (HFONT)::SelectObject(hMemDC, m_hFontName); |
| | | ::SetTextColor(hMemDC, pItem->bHighlight ? m_crItemNameText[1] : m_crItemNameText[0]); |
| | | ::DrawText(hMemDC, pItem->text, (int)strlen(pItem->text), &rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | ::DrawText(hMemDC, pItem->text, (int)strlen(pItem->text), &rcItem, |
| | | DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | |
| | | // indicators vertical column layout |
| | | const int indicatorSize = m_nIndicatorSize; |
| | | const int indicatorMargin = m_nIndicatorMargin; |
| | | const int indicatorX = rcItem.left + 5; |
| | | |
| | | // æ·»å ä¸ä¸ªå°ç»¿ç¹æç¤ºå¨ |
| | | if(pItem->bShowIndicator[0]){ |
| | | RECT rcIndicator; |
| | | rcIndicator.left = rcItem.left + 5; |
| | | rcIndicator.top = rcItem.top + 5; |
| | | rcIndicator.right = rcIndicator.left + 12; |
| | | rcIndicator.bottom = rcIndicator.top + 12; |
| | | HRGN hRgn = CreateRoundRectRgn(rcIndicator.left, rcIndicator.top, rcIndicator.right, rcIndicator.bottom, 2, 2); |
| | | ::FillRgn(hMemDC, hRgn, hbrIndicator); |
| | | ::FrameRgn(hMemDC, hRgn, hbrItemFrame[0], 1, 1); |
| | | ::DeleteObject(hRgn); |
| | | for (int k = 0; k < EQITEM_INDICATOR_COUNT; ++k) { |
| | | BYTE indicatorState = pItem->nIndicatorState[k]; |
| | | if (indicatorState == INDICATOR_STATE_HIDDEN) { |
| | | continue; |
| | | } |
| | | |
| | | RECT rcIndicator; |
| | | rcIndicator.left = indicatorX; |
| | | rcIndicator.top = rcItem.top + 5 + k * (indicatorSize + indicatorMargin); |
| | | rcIndicator.right = rcIndicator.left + indicatorSize; |
| | | rcIndicator.bottom = rcIndicator.top + indicatorSize; |
| | | |
| | | RECT rcInner = rcIndicator; |
| | | ::InflateRect(&rcInner, -1, -1); |
| | | ::FillRect(hMemDC, &rcInner, indicatorState == INDICATOR_STATE_HIGHLIGHT |
| | | ? hbrIndicator : hbrIndicatorGray); |
| | | ::FrameRect(hMemDC, &rcIndicator, hbrItemFrame[0]); |
| | | } |
| | | |
| | | // ID ææ¬ï¼éå°å· itemï¼ |
| | | if (pItem->nShowType != ITEM_SMALL) { |
| | | RECT rcId = rcItem; |
| | | rcId.left += 5; |
| | |
| | | strId.Format(_T("ID:%d"), pItem->id); |
| | | ::SelectObject(hMemDC, m_hFontId); |
| | | ::SetTextColor(hMemDC, pItem->bHighlight ? m_crItemIdText[1] : m_crItemIdText[0]); |
| | | ::DrawText(hMemDC, strId, (int)strId.GetLength(), &rcId, DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | ::DrawText(hMemDC, strId, (int)strId.GetLength(), &rcId, |
| | | DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | } |
| | | |
| | | |
| | | // å¨ç»ææä¸ç»pin |
| | | // å¨ç»æææ¶ä¸ç»å¶ pin |
| | | if (m_pAnimationItem == pItem) { |
| | | ::SelectObject(hMemDC, hFontOld); |
| | | continue; |
| | | } |
| | | |
| | | |
| | | // ç»å¶pin |
| | | // ç»å¶ pin |
| | | RECT rcPin, rcPin2, rcPinText; |
| | | CPtrArray *pPins; |
| | | rcPinText.left = rcItem.left + 8; |
| | | rcPinText.right = rcItem.right - 8; |
| | | |
| | | |
| | | // in pins |
| | | PIN *pPin = NULL; |
| | |
| | | rcPin2.top = rcPin.top + 1; |
| | | rcPin2.bottom = rcPin.bottom - 1; |
| | | nPinState = GetPinState(pPin); |
| | | ::FillRect(hMemDC, &rcPin2, nPinState == 0 ? (pItem->bHighlight ? hbrItemBackground[1] : hbrItemBackground[0]) : hbrPinBackground[nPinState]); |
| | | ::FillRect(hMemDC, &rcPin2, |
| | | nPinState == 0 |
| | | ? (pItem->bHighlight ? hbrItemBackground[1] : hbrItemBackground[0]) |
| | | : hbrPinBackground[nPinState]); |
| | | |
| | | if (pItem->nShowType != ITEM_SMALL) { |
| | | rcPinText.top = rcPin.top - 12; |
| | | rcPinText.bottom = rcPin.bottom + 12; |
| | | ::SetTextColor(hMemDC, pItem->bHighlight ? m_crItemIdText[1] : m_crItemIdText[0]); |
| | | ::DrawText(hMemDC, pPin->text, (int)strlen(pPin->text), &rcPinText, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | ::DrawText(hMemDC, pPin->text, (int)strlen(pPin->text), &rcPinText, |
| | | DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // out pins |
| | | pPins = (CPtrArray *)pItem->pOutPins; |
| | |
| | | rcPin2.top = rcPin.top + 1; |
| | | rcPin2.bottom = rcPin.bottom - 1; |
| | | nPinState = GetPinState(pPin); |
| | | ::FillRect(hMemDC, &rcPin2, nPinState == 0 ? (pItem->bHighlight ? hbrItemBackground[1] : hbrItemBackground[0]) : hbrPinBackground[nPinState]); |
| | | ::FillRect(hMemDC, &rcPin2, |
| | | nPinState == 0 |
| | | ? (pItem->bHighlight ? hbrItemBackground[1] : hbrItemBackground[0]) |
| | | : hbrPinBackground[nPinState]); |
| | | |
| | | if (pItem->nShowType != ITEM_SMALL) { |
| | | rcPinText.top = rcPin.top - 12; |
| | | rcPinText.bottom = rcPin.bottom + 12; |
| | | ::SetTextColor(hMemDC, pItem->bHighlight ? m_crItemIdText[1] : m_crItemIdText[0]); |
| | | ::DrawText(hMemDC, pPin->text, (int)strlen(pPin->text), &rcPinText, DT_RIGHT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | ::DrawText(hMemDC, pPin->text, (int)strlen(pPin->text), &rcPinText, |
| | | DT_RIGHT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | } |
| | | } |
| | | } |
| | | |
| | | ::DeleteObject(hbrItemFrame); |
| | | ::SelectObject(hMemDC, hFontOld); |
| | | } |
| | | |
| | | |
| | | // ç»å¶è¿æ¥çº¿ï¼ä¿å线æ¡å¨æåç»å¶ |
| | | // åç»å¶è¿æ¥çº¿ |
| | | for (int i = 0; i < nItemCount; i++) { |
| | | EQITEM *pItem = (EQITEM*)m_arItem.GetAt(i); |
| | | if (pItem->nFlashFlag == 1) { |
| | |
| | | |
| | | PIN *pPin = NULL; |
| | | CPtrArray *pPins; |
| | | |
| | | // out pins边线 |
| | | RECT rcItem1, rcItem2; |
| | | |
| | | // out pins 边线 |
| | | pPins = (CPtrArray *)pItem->pOutPins; |
| | | for (int j = 0; j < pPins->GetSize(); j++) { |
| | | pPin = (PIN *)pPins->GetAt(j); |
| | |
| | | if (GetPinPoint(pPin, &pt1) && GetPinPoint(pPin->pConnectedPin, &pt2)) { |
| | | GetItemRect(pItem, &rcItem1); |
| | | GetItemRect(pPin->pConnectedPin->pItem, &rcItem2); |
| | | DrawPinConnectedLine(&graphics, &brush1, pPin == m_pSelLineOutPin ? &pen2 : &pen1, |
| | | DrawPinConnectedLine(&graphics, &brush1, |
| | | pPin == m_pSelLineOutPin ? &pen2 : &pen1, |
| | | &pt1, &pt2, &rcItem1, &rcItem2, pPin); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // å é¤ brush |
| | | for (int i = 0; i < 3; i++) { |
| | | ::DeleteObject(hbrPinBackground[i]); |
| | | } |
| | |
| | | ::DeleteObject(hbrItemFrame[0]); |
| | | ::DeleteObject(hbrItemFrame[1]); |
| | | ::DeleteObject(hbrIndicator); |
| | | ::DeleteObject(hbrIndicatorGray); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | // EndPaint |
| | | ::BitBlt(hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, |
| | |
| | | ::DeleteObject(hBitmap); |
| | | ::DeleteDC(hMemDC); |
| | | |
| | | |
| | | return 1; |
| | | } |
| | | |
| | | |
| | | /* |
| | | * WM_SIZE |
| | |
| | | |
| | | |
| | | /* |
| | | * è®¾ç½®èæ¯é¢è² |
| | | * color -- èæ¯è² |
| | | * è®¾ç½®èæ¯é¢è² |
| | | * color -- èæ¯è² |
| | | */ |
| | | void CEqsGraphWnd::SetBkgndColor(COLORREF color) |
| | | { |
| | |
| | | } |
| | | |
| | | /* |
| | | * è¾¹æ¡é¢è² |
| | | * color -- è¾¹æ¡è² |
| | | * è¾¹æ¡é¢è² |
| | | * color -- è¾¹æ¡è² |
| | | */ |
| | | void CEqsGraphWnd::SetFrameColor(COLORREF color) |
| | | { |
| | |
| | | SetTimer(m_hWnd, TIMER_ANIMATION_RECT, uElpase, NULL); |
| | | } |
| | | |
| | | void CEqsGraphWnd::ShowItemIndicator(DWORD_PTR dwItemData, BOOL bShow) |
| | | void CEqsGraphWnd::ShowItemIndicator(DWORD_PTR dwItemData, int state, int nIndex) |
| | | { |
| | | if (nIndex < 0 || nIndex >= EQITEM_INDICATOR_COUNT) { |
| | | return; |
| | | } |
| | | |
| | | EQITEM* pItem = GetItem(dwItemData); |
| | | if (pItem != nullptr) { |
| | | pItem->bShowIndicator[0] = bShow; |
| | | pItem->nIndicatorState[nIndex] = (BYTE)state; |
| | | ::InvalidateRect(m_hWnd, nullptr, TRUE); |
| | | } |
| | | } |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include <functional> |
| | | |
| | | |
| | |
| | | #define MAX(X,Y) (((X)>(Y))?(X):(Y)) |
| | | #endif |
| | | |
| | | #define EQITEM_INDICATOR_COUNT 8 |
| | | |
| | | |
| | | enum EIndicatorState |
| | | { |
| | | INDICATOR_STATE_HIDDEN = 0, |
| | | INDICATOR_STATE_HIGHLIGHT = 1, |
| | | INDICATOR_STATE_GRAY = 2, |
| | | }; |
| | | |
| | | typedef struct tagEQSGRAPHWND_NMHDR |
| | | { |
| | | NMHDR nmhdr; |
| | |
| | | DWORD_PTR pInPins; |
| | | DWORD_PTR pOutPins; |
| | | int nFlashFlag; |
| | | BOOL bShowIndicator[2]; |
| | | BYTE nIndicatorState[EQITEM_INDICATOR_COUNT]; // 0=éè, 1=é«äº®, 2=ç°è² |
| | | } EQITEM; |
| | | |
| | | typedef struct tagPIN |
| | |
| | | void SetItemPos(EQITEM* pItem, int x, int y); |
| | | void FlashItem(EQITEM* pItem); |
| | | void AnimationItem(EQITEM*pItem); |
| | | void ShowItemIndicator(DWORD_PTR dwItemData, BOOL bShow); |
| | | void ShowItemIndicator(DWORD_PTR dwItemData, int state, int nIndex = 0); |
| | | void SetIndicatorSize(int nSize); |
| | | void SetIndicatorMargin(int nMargin); |
| | | |
| | | private: |
| | | void Init(); |
| | |
| | | EQITEM* m_pFlashItem; |
| | | EQITEM* m_pAnimationItem; |
| | | PIN * m_pCurPin; |
| | | PIN * m_pSelLineOutPin; // éä¸çè¿çº¿ç两个pinä¸çout pin |
| | | PIN * m_pSelLineOutPin; // éä¸çè¿çº¿ç两个pinä¸çout pin |
| | | |
| | | private: |
| | | HWND m_hWnd; |
| | |
| | | HFONT m_hFontTitle; |
| | | |
| | | private: |
| | | BOOL m_bUseGdiPlus; // 使ç¨GDI+ç»å¾ï¼ |
| | | COLORREF m_crItemBackground[2]; // itemçé¢è²ï¼normalï¼ active |
| | | COLORREF m_crItemFrame[2]; // itemçè¾¹æ¡ï¼normalï¼ active |
| | | BOOL m_bUseGdiPlus; // 使ç¨GDI+ç»å¾ï¼ |
| | | COLORREF m_crItemBackground[2]; // itemçé¢è²ï¼normalï¼ active |
| | | COLORREF m_crItemFrame[2]; // itemçè¾¹æ¡ï¼normalï¼ active |
| | | COLORREF m_crItemNameText[2]; |
| | | COLORREF m_crItemIdText[2]; |
| | | COLORREF m_crPinBkgnd[3]; // pinçé¢è²ï¼normal, active, enable connect |
| | | COLORREF m_crPinBkgnd[3]; // pinçé¢è²ï¼normal, active, enable connect |
| | | int m_nCurSel; |
| | | EqsGraphListener m_listener; |
| | | CPtrArray m_arItem; |
| | |
| | | int m_nItemRound; |
| | | |
| | | private: |
| | | int m_nStageCx; // ç»å¸å¤§å° |
| | | int m_nStageCx; // ç»å¸å¤§å° |
| | | int m_nStageCy; |
| | | int m_nOffsetX; |
| | | int m_nOffsetY; |
| | | int m_nIndicatorSize; |
| | | int m_nIndicatorMargin; |
| | | |
| | | // å¨ç» |
| | | // å¨ç» |
| | | RECTF m_rcAnimation; |
| | | RECTF m_rcAninationStep; |
| | | int m_nAninationStep; |
| | | int m_nAninationDuration; // ms |
| | | |
| | | // åä½ |
| | | // åä½ |
| | | HFONT m_hFontName; |
| | | HFONT m_hFontId; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "HmLabel.h" |
| | | |
| | | |
| | | CHmLabel::CHmLabel() |
| | | { |
| | | m_crFrame = RGB(128, 128, 128); |
| | | m_crBackground = RGB(255, 0, 0); |
| | | m_crForeground = RGB(255, 255, 255); |
| | | m_hFont = NULL; |
| | | m_hFontNote = NULL; |
| | | } |
| | | |
| | | |
| | | CHmLabel::~CHmLabel() |
| | | { |
| | | if (m_hFont != NULL) { |
| | | ::DeleteObject(m_hFont); |
| | | m_hFont = NULL; |
| | | } |
| | | |
| | | if (m_hFontNote != NULL) { |
| | | ::DeleteObject(m_hFontNote); |
| | | m_hFontNote = NULL; |
| | | } |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CHmLabel, CStatic) |
| | | ON_WM_PAINT() |
| | | ON_WM_NCPAINT() |
| | | END_MESSAGE_MAP() |
| | | |
| | | void CHmLabel::setText(CString strText) |
| | | { |
| | | SetWindowText(strText); |
| | | Invalidate(); |
| | | } |
| | | |
| | | void CHmLabel::setNote1(CString strNote1) |
| | | { |
| | | m_strNote1 = strNote1; |
| | | } |
| | | |
| | | void CHmLabel::setFontSize(int size) |
| | | { |
| | | if (m_hFont != NULL) { |
| | | ::DeleteObject(m_hFont); |
| | | m_hFont = NULL; |
| | | } |
| | | |
| | | m_hFont = CreateFont(size, 0, 0, 0, FW_MEDIUM, |
| | | FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, |
| | | CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, _T("å®ä½")); |
| | | } |
| | | |
| | | void CHmLabel::setNoteFontSize(int size) |
| | | { |
| | | if (m_hFontNote != NULL) { |
| | | ::DeleteObject(m_hFontNote); |
| | | m_hFontNote = NULL; |
| | | } |
| | | |
| | | m_hFontNote = CreateFont(size, 0, 0, 0, FW_MEDIUM, |
| | | FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, |
| | | CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, _T("å®ä½")); |
| | | } |
| | | |
| | | void CHmLabel::setNoteTextColor(COLORREF color, BOOL bInvalidate/* = FALSE*/) |
| | | { |
| | | m_crNote = color; |
| | | if (bInvalidate) Invalidate(TRUE); |
| | | } |
| | | |
| | | void CHmLabel::setBackground(COLORREF color, BOOL bInvalidate/* = FALSE*/) |
| | | { |
| | | m_crBackground = color; |
| | | if (bInvalidate) Invalidate(TRUE); |
| | | } |
| | | |
| | | void CHmLabel::setForeground(COLORREF color, BOOL bInvalidate/* = FALSE*/) |
| | | { |
| | | m_crForeground = color; |
| | | if (bInvalidate) Invalidate(TRUE); |
| | | } |
| | | |
| | | void CHmLabel::OnPaint() |
| | | { |
| | | CPaintDC dc(this); // device context for painting |
| | | // TODO: 卿¤å¤æ·»å æ¶æ¯å¤çç¨åºä»£ç |
| | | // ä¸ä¸ºç»å¾æ¶æ¯è°ç¨ CStatic::OnPaint() |
| | | |
| | | |
| | | HDC hMemDC; |
| | | HBITMAP hBitmap; |
| | | RECT rcClient; |
| | | CString strText; |
| | | HBRUSH hBrushBK; |
| | | |
| | | |
| | | GetClientRect(&rcClient); |
| | | hMemDC = ::CreateCompatibleDC(dc.m_hDC); |
| | | hBitmap = ::CreateCompatibleBitmap(dc.m_hDC, rcClient.right - rcClient.left, |
| | | rcClient.bottom - rcClient.top); |
| | | ::SelectObject(hMemDC, hBitmap); |
| | | |
| | | |
| | | // èæ¯é¢è² |
| | | hBrushBK = CreateSolidBrush(m_crBackground); |
| | | ::FillRect(hMemDC, &rcClient, hBrushBK); |
| | | DeleteObject(hBrushBK); |
| | | |
| | | |
| | | // æå |
| | | char szText[256]; |
| | | GetWindowText(szText, 256); |
| | | RECT rcText = rcClient; |
| | | SetBkMode(hMemDC, TRANSPARENT); |
| | | SetTextColor(hMemDC, m_crForeground); |
| | | ::SelectObject(hMemDC, m_hFont == NULL ? (HFONT)GetStockObject(DEFAULT_GUI_FONT) : m_hFont); |
| | | ::DrawTextA(hMemDC, szText, (int)strlen(szText), &rcText, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | |
| | | |
| | | // Note1 |
| | | SetTextColor(hMemDC, m_crNote); |
| | | ::SelectObject(hMemDC, m_hFontNote == NULL ? (HFONT)GetStockObject(DEFAULT_GUI_FONT) : m_hFontNote); |
| | | ::DrawText(hMemDC, m_strNote1, m_strNote1.GetLength(), &rcClient, DT_CENTER | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS); |
| | | |
| | | |
| | | // EndPaint |
| | | ::BitBlt(dc.m_hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, |
| | | hMemDC, 0, 0, SRCCOPY); |
| | | ::DeleteObject(hBitmap); |
| | | ::DeleteDC(hMemDC); |
| | | } |
| | | |
| | | |
| | | void CHmLabel::OnNcPaint() |
| | | { |
| | | // TODO: 卿¤å¤æ·»å æ¶æ¯å¤çç¨åºä»£ç |
| | | // ä¸ä¸ºç»å¾æ¶æ¯è°ç¨ CStatic::OnNcPaint() |
| | | long styleEx = GetWindowLong(m_hWnd, GWL_EXSTYLE); |
| | | if ((styleEx & WS_EX_CLIENTEDGE) == WS_EX_CLIENTEDGE) { |
| | | |
| | | RECT rect, rcClient; |
| | | GetClientRect(&rcClient); |
| | | ::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.left); |
| | | ::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.right); |
| | | GetWindowRect(&rect); |
| | | ::OffsetRect(&rcClient, -rect.left, -rect.top); |
| | | |
| | | rect.right -= rect.left; |
| | | rect.bottom -= rect.top; |
| | | rect.left = 0; |
| | | rect.top = 0; |
| | | |
| | | HRGN hRgnWnd = CreateRectRgnIndirect(&rect); |
| | | HRGN hRgnClient = CreateRectRgnIndirect(&rcClient); |
| | | |
| | | HBRUSH hBrushBK, hBrushFrame; |
| | | HDC hDC = ::GetWindowDC(m_hWnd); |
| | | ::SelectClipRgn(hDC, hRgnWnd); |
| | | ::ExtSelectClipRgn(hDC, hRgnClient, RGN_DIFF); |
| | | |
| | | hBrushBK = CreateSolidBrush(m_crBackground); |
| | | ::FillRect(hDC, &rect, hBrushBK); |
| | | DeleteObject(hBrushBK); |
| | | |
| | | hBrushFrame = CreateSolidBrush(m_crFrame); |
| | | ::FrameRect(hDC, &rect, hBrushFrame); |
| | | |
| | | ::DeleteObject(hRgnWnd); |
| | | ::DeleteObject(hRgnClient); |
| | | DeleteObject(hBrushFrame); |
| | | ::ReleaseDC(m_hWnd, hDC); |
| | | } |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | class CHmLabel : public CStatic |
| | | { |
| | | public: |
| | | CHmLabel(); |
| | | ~CHmLabel(); |
| | | |
| | | public: |
| | | void setText(CString strText); |
| | | void setNote1(CString strNote1); |
| | | void setFontSize(int size); |
| | | void setNoteFontSize(int size); |
| | | void setBackground(COLORREF color, BOOL bInvalidate = FALSE); |
| | | void setForeground(COLORREF color, BOOL bInvalidate = FALSE); |
| | | void setNoteTextColor(COLORREF color, BOOL bInvalidate = FALSE); |
| | | |
| | | private: |
| | | COLORREF m_crFrame; |
| | | COLORREF m_crBackground; |
| | | COLORREF m_crForeground; |
| | | COLORREF m_crNote; |
| | | HFONT m_hFont; |
| | | HFONT m_hFontNote; |
| | | |
| | | private: |
| | | CString m_strNote1; |
| | | |
| | | public: |
| | | DECLARE_MESSAGE_MAP() |
| | | afx_msg void OnPaint(); |
| | | afx_msg void OnNcPaint(); |
| | | }; |
| | | |
| | |
| | | m_nTimeout = 45; |
| | | m_nResponseTime = 0; |
| | | m_pContext = NULL; |
| | | m_pSendMessage = NULL; |
| | | m_hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); |
| | | } |
| | | |
| | |
| | | m_nTimeout = nTimeout; |
| | | m_nResponseTime = 0; |
| | | m_pContext = NULL; |
| | | m_pSendMessage = NULL; |
| | | m_hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); |
| | | } |
| | | |
| | |
| | | m_bNeedWaitReply = FALSE; |
| | | m_nTimeout = 45; |
| | | m_nResponseTime = 0; |
| | | if (m_pSendMessage != NULL) { |
| | | HSMS_Destroy1Message(m_pSendMessage); |
| | | m_pSendMessage = NULL; |
| | | } |
| | | ::ResetEvent(m_hEvent); |
| | | } |
| | | |
| | |
| | | |
| | | void CHsmsAction::setSendMessage(IMessage* pMessage) |
| | | { |
| | | if (m_pSendMessage != NULL && m_pSendMessage != pMessage) { |
| | | HSMS_Destroy1Message(m_pSendMessage); |
| | | } |
| | | m_pSendMessage = pMessage; |
| | | } |
| | | |
| | |
| | | int CHsmsAction::serialize(char* pszBuffer, int nBufferSize) |
| | | { |
| | | int index = 0; |
| | | if (m_pSendMessage == NULL) { |
| | | return 0; |
| | | } |
| | | if (pszBuffer == nullptr) { |
| | | index += sizeof(int); |
| | | index += sizeof(m_nTimeout); |
| | | index += sizeof(int); |
| | | index += sizeof(BOOL); |
| | | index += m_pSendMessage->serialize(pszBuffer, nBufferSize); |
| | | index += m_pSendMessage->serialize(nullptr, 0); |
| | | |
| | | return index; |
| | | } |
| | |
| | | memcpy(&m_bNeedWaitReply, &pszBuffer[index], sizeof(BOOL)); |
| | | index += sizeof(BOOL); |
| | | |
| | | HSMS_Create1Message(m_pSendMessage, 1, 1 | REPLY, 1, 1); |
| | | if (m_pSendMessage != NULL) { |
| | | HSMS_Destroy1Message(m_pSendMessage); |
| | | m_pSendMessage = NULL; |
| | | } |
| | | if (HSMS_Create1Message(m_pSendMessage, 1, 1 | REPLY, 1, 1) != 0 || m_pSendMessage == NULL) { |
| | | return -1; |
| | | } |
| | | int nRet = m_pSendMessage->unserialize(&pszBuffer[index], nBufferSize - index); |
| | | if (nRet < 0) return nRet; |
| | | |
| | |
| | | #include "Log.h" |
| | | #include "Model.h" |
| | | #include "Common.h" |
| | | #include "RecipeManager.h" |
| | | #include <time.h> |
| | | #include <iostream> |
| | | #include <time.h> |
| | | #include <stdlib.h> |
| | | #include <string.h> |
| | | #include <algorithm> |
| | | #include <set> |
| | | #include <regex> |
| | | #include <sstream> |
| | | |
| | | // ---- Encoding helpers ---- |
| | | static bool hasUtf8Bom(const std::string& s) |
| | | { |
| | | return s.size() >= 3 && |
| | | static_cast<unsigned char>(s[0]) == 0xEF && |
| | | static_cast<unsigned char>(s[1]) == 0xBB && |
| | | static_cast<unsigned char>(s[2]) == 0xBF; |
| | | } |
| | | |
| | | static bool isLikelyUtf8(const std::string& s) |
| | | { |
| | | // Simple heuristic: try to convert; if success without errors, treat as UTF-8. |
| | | int wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), (int)s.size(), nullptr, 0); |
| | | return wlen > 0; |
| | | } |
| | | |
| | | static CStringW Utf8ToWide(const char* psz) |
| | | { |
| | | if (psz == nullptr) return L""; |
| | | int wlen = MultiByteToWideChar(CP_UTF8, 0, psz, -1, nullptr, 0); |
| | | if (wlen <= 0) return L""; |
| | | CStringW ws; |
| | | LPWSTR buf = ws.GetBufferSetLength(wlen - 1); |
| | | MultiByteToWideChar(CP_UTF8, 0, psz, -1, buf, wlen); |
| | | ws.ReleaseBuffer(); |
| | | return ws; |
| | | } |
| | | |
| | | static CStringW AnsiToWide(const char* psz) |
| | | { |
| | | if (psz == nullptr) return L""; |
| | | int wlen = MultiByteToWideChar(CP_ACP, 0, psz, -1, nullptr, 0); |
| | | if (wlen <= 0) return L""; |
| | | CStringW ws; |
| | | LPWSTR buf = ws.GetBufferSetLength(wlen - 1); |
| | | MultiByteToWideChar(CP_ACP, 0, psz, -1, buf, wlen); |
| | | ws.ReleaseBuffer(); |
| | | return ws; |
| | | } |
| | | // ---- End helpers ---- |
| | | |
| | | // ControlState values (keep in sync with Model::ControlState / VariableList.txt) |
| | | static constexpr uint8_t kControlStateOnlineRemote = 5; |
| | | |
| | | |
| | | const char ACK[2] = {0, 1}; |
| | | const char* ACK0 = &ACK[0]; |
| | | const char* ACK1 = &ACK[1]; |
| | | |
| | | // Log SECS-II message briefly to avoid huge strings causing issues. |
| | | static void LogSecsMessageBrief(const char* tag, IMessage* pMessage, size_t maxLen = 1024) |
| | | { |
| | | if (pMessage == nullptr) return; |
| | | const char* msgStr = pMessage->toString(); |
| | | if (msgStr == nullptr) return; |
| | | std::string buf(msgStr); |
| | | if (buf.size() > maxLen) { |
| | | buf = buf.substr(0, maxLen) + "...<truncated>"; |
| | | } |
| | | LOGI("%s%s", tag, buf.c_str()); |
| | | } |
| | | |
| | | unsigned __stdcall CimWorkThreadFunction(LPVOID lpParam) |
| | | { |
| | |
| | | m_listener.onEQOffLine = nullptr; |
| | | m_listener.onEQOnLine = nullptr; |
| | | m_listener.onCommand = nullptr; |
| | | m_listener.onEQConstantRequest = nullptr; |
| | | m_listener.onEQConstantSend = nullptr; |
| | | m_pActiveAction = nullptr; |
| | | InitializeCriticalSection(&m_criticalSection); |
| | | } |
| | |
| | | ASSERT(pParent); |
| | | ASSERT(pVariable); |
| | | |
| | | std::string svNote("SV"); |
| | | { |
| | | SERVO::CVariable* pDef = getVariable((int)pVariable->getVarialbleId()); |
| | | if (pDef == nullptr) { |
| | | pDef = pVariable; |
| | | } |
| | | auto& name = pDef->getName(); |
| | | if (!name.empty()) { |
| | | svNote += " -> "; |
| | | svNote += name; |
| | | } |
| | | } |
| | | |
| | | ISECS2Item* pItemList; |
| | | SERVO::SVFromat format = pVariable->getFormat(); |
| | | switch (format) |
| | | { |
| | | case SERVO::SVFromat::U1: |
| | | pParent->addU1Item((unsigned char)pVariable->getIntValue(), "SV"); |
| | | pParent->addU1Item((unsigned char)pVariable->getIntValue(), svNote.c_str()); |
| | | break; |
| | | case SERVO::SVFromat::U2: |
| | | pParent->addU2Item((unsigned char)pVariable->getIntValue(), "SV"); |
| | | pParent->addU2Item((unsigned char)pVariable->getIntValue(), svNote.c_str()); |
| | | break; |
| | | case SERVO::SVFromat::I2: |
| | | pParent->addI2Item((unsigned char)pVariable->getIntValue(), "SV"); |
| | | pParent->addI2Item((unsigned char)pVariable->getIntValue(), svNote.c_str()); |
| | | break; |
| | | case SERVO::SVFromat::A20: |
| | | case SERVO::SVFromat::A50: |
| | | pParent->addItem(pVariable->getValue().c_str(), "SV"); |
| | | pParent->addItem(pVariable->getValue().c_str(), svNote.c_str()); |
| | | break; |
| | | case SERVO::SVFromat::L: |
| | | pItemList = pParent->addItem(); |
| | |
| | | |
| | | void CHsmsPassive::unlinkEventReport(unsigned int CEID) |
| | | { |
| | | LOGI("<CHsmsPassive>unlinkEventReport enter"); |
| | | SERVO::CCollectionEvent* pEvent = getEvent(CEID); |
| | | if (pEvent != nullptr) { |
| | | pEvent->setReport(nullptr); |
| | | LOGI("<CHsmsPassive>unlink Event Report.CEID=%d", CEID); |
| | | } |
| | | } |
| | | |
| | | bool CHsmsPassive::shouldSpool(uint8_t streamId, uint8_t functionId) const |
| | | { |
| | | // Comment: stream 1 is not spooled |
| | | if (streamId == 1) return false; |
| | | |
| | | // Comment: m=0 turns off all streams and fns |
| | | if (!m_spoolingEnabled) return false; |
| | | |
| | | // Blacklist semantics: in map => do NOT spool/cache. |
| | | // Not in map => allow spooling by default. |
| | | auto it = m_spoolBlacklistByStream.find(streamId); |
| | | if (it == m_spoolBlacklistByStream.end()) return true; |
| | | |
| | | // Empty set => all functions in this stream |
| | | if (it->second.empty()) return true; |
| | | |
| | | return it->second.find(functionId) == it->second.end(); |
| | | } |
| | | |
| | | SERVO::CReport* CHsmsPassive::defineReport(unsigned int RPTID, std::vector<unsigned int>& vids) |
| | | { |
| | | LOGI("<CHsmsPassive>defineReport enter"); |
| | | // æ·»å å®ä¹report |
| | | SERVO::CReport* pReport = new SERVO::CReport(RPTID, vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable(vid); |
| | | if (pVariable == nullptr) { |
| | | pVariable = getDataVariable(vid); |
| | | } |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | LOGI("<CHsmsPassive>defineReport RPTID=%d", RPTID); |
| | | } |
| | | } |
| | | m_reports.push_back(pReport); |
| | | writeReportsToFile(m_strReportFilepath); |
| | | |
| | | return pReport; |
| | | } |
| | |
| | | |
| | | int CHsmsPassive::onRecvMsg(IMessage* pMessage) |
| | | { |
| | | LOGI("onRecvMsg:%s", pMessage->toString()); |
| | | // LOGI("onRecvMsg:%s", pMessage->toString()); |
| | | Lock(); |
| | | if (m_pActiveAction != nullptr && |
| | | (m_pActiveAction->getSendMessage()->getHeader()->systemBytes == pMessage->getHeader()->systemBytes)) { |
| | |
| | | |
| | | int CHsmsPassive::loadVarialbles(const char* pszFilepath) |
| | | { |
| | | CStdioFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead)) { |
| | | m_strVariableFilepath = pszFilepath; |
| | | m_bVariableUtf8 = false; |
| | | m_bVariableUtf8Bom = false; |
| | | // å
读åå§åèï¼åç»åæ UTF-8/BOM ææ¬å°ç¼ç è½¬æ¢ |
| | | CFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | |
| | | std::regex pattern("^\\d+,.*"); // å¹é
以æ°å+éå·å¼å¤´çå符串 |
| | | const ULONGLONG nLen = file.GetLength(); |
| | | if (nLen == 0) { |
| | | return -1; |
| | | } |
| | | |
| | | std::string buffer; |
| | | buffer.resize(static_cast<size_t>(nLen)); |
| | | file.Read(buffer.data(), static_cast<UINT>(nLen)); |
| | | file.Close(); |
| | | |
| | | const unsigned char* bytes = reinterpret_cast<const unsigned char*>(buffer.data()); |
| | | size_t offset = 0; |
| | | CStringW content; |
| | | |
| | | // UTF-8 BOM |
| | | if (nLen >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) { |
| | | offset = 3; |
| | | m_bVariableUtf8 = true; |
| | | m_bVariableUtf8Bom = true; |
| | | } |
| | | |
| | | // UTF-16 LE BOM |
| | | if (nLen >= 2 && bytes[0] == 0xFF && bytes[1] == 0xFE) { |
| | | const wchar_t* wdata = reinterpret_cast<const wchar_t*>(buffer.data() + 2); |
| | | const size_t wlen = (nLen - 2) / sizeof(wchar_t); |
| | | content.SetString(wdata, static_cast<int>(wlen)); |
| | | } |
| | | // UTF-16 BE BOM |
| | | else if (nLen >= 2 && bytes[0] == 0xFE && bytes[1] == 0xFF) { |
| | | const size_t wlen = (nLen - 2) / sizeof(wchar_t); |
| | | std::wstring temp; |
| | | temp.reserve(wlen); |
| | | for (size_t i = 0; i < wlen; ++i) { |
| | | wchar_t ch = static_cast<wchar_t>(bytes[2 + i * 2] << 8 | bytes[2 + i * 2 + 1]); |
| | | temp.push_back(ch); |
| | | } |
| | | content = temp.c_str(); |
| | | } |
| | | // å°è¯ UTF-8ï¼å«æ BOMï¼ |
| | | else { |
| | | auto tryUtf8 = [&](size_t off) -> bool { |
| | | int need = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buffer.data() + off, |
| | | static_cast<int>(buffer.size() - off), nullptr, 0); |
| | | if (need <= 0) return false; |
| | | std::wstring temp; |
| | | temp.resize(need); |
| | | MultiByteToWideChar(CP_UTF8, 0, buffer.data() + off, |
| | | static_cast<int>(buffer.size() - off), temp.data(), need); |
| | | content = temp.c_str(); |
| | | m_bVariableUtf8 = true; |
| | | return true; |
| | | }; |
| | | |
| | | if (!tryUtf8(offset)) { |
| | | // åéå°æ¬å°ä»£ç 页 |
| | | int need = MultiByteToWideChar(CP_ACP, 0, buffer.data(), static_cast<int>(buffer.size()), nullptr, 0); |
| | | if (need > 0) { |
| | | std::wstring temp; |
| | | temp.resize(need); |
| | | MultiByteToWideChar(CP_ACP, 0, buffer.data(), static_cast<int>(buffer.size()), temp.data(), need); |
| | | content = temp.c_str(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (content.IsEmpty()) { |
| | | return -1; |
| | | } |
| | | |
| | | std::wregex pattern(L"^\\d+,.+"); // å¹é
以æ°å+éå·å¼å¤´çå符串 |
| | | std::vector<SERVO::CVariable*> variables; |
| | | int index, last; |
| | | CString strLine; |
| | | CString strId, strName, strFormat, strRemark; |
| | | while (file.ReadString(strLine)) { |
| | | if (!std::regex_match((LPTSTR)(LPCTSTR)strLine, pattern)) { |
| | | CStringW strLine; |
| | | CStringW strId, strName, strFormat, strRemark; |
| | | std::wstringstream ss(content.GetString()); |
| | | auto narrowFromW = [](const CStringW& s) -> std::string { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return {}; |
| | | std::string out(static_cast<size_t>(need - 1), '\0'); |
| | | WideCharToMultiByte(CP_ACP, 0, s, -1, out.data(), need, nullptr, nullptr); |
| | | return out; |
| | | }; |
| | | std::wstring line; |
| | | while (std::getline(ss, line, L'\n')) { |
| | | strLine = line.c_str(); |
| | | strLine.Trim(); |
| | | if (strLine.IsEmpty()) continue; |
| | | if (!std::regex_match(static_cast<LPCWSTR>(strLine), pattern)) { |
| | | continue; |
| | | } |
| | | |
| | | last = 0; |
| | | index = strLine.Find(",", last); |
| | | index = strLine.Find(L",", last); |
| | | if (index < 0) continue; |
| | | strId = strLine.Left(index); |
| | | last = index + 1; |
| | | |
| | | index = strLine.Find(",", last); |
| | | index = strLine.Find(L",", last); |
| | | if (index < 0) continue; |
| | | strName = strLine.Mid(last, index - last); |
| | | last = index + 1; |
| | | |
| | | index = strLine.Find(",", last); |
| | | index = strLine.Find(L",", last); |
| | | if (index < 0) continue; |
| | | strFormat = strLine.Mid(last, index - last); |
| | | strRemark = strLine.Right(strLine.GetLength() - index - 1); |
| | | strRemark.Replace(_T("\\r\\n"), _T("\r\n")); |
| | | strRemark.Replace(L"\\r\\n", L"\r\n"); |
| | | |
| | | std::string sId = narrowFromW(strId); |
| | | std::string sName = narrowFromW(strName); |
| | | std::string sFormat = narrowFromW(strFormat); |
| | | std::string sRemark = narrowFromW(strRemark); |
| | | |
| | | SERVO::CVariable* pVarialble = new SERVO::CVariable( |
| | | (LPTSTR)(LPCTSTR)strId, (LPTSTR)(LPCTSTR)strName, (LPTSTR)(LPCTSTR)strFormat, (LPTSTR)(LPCTSTR)strRemark); |
| | | sId.c_str(), |
| | | sName.c_str(), |
| | | sFormat.c_str(), |
| | | sRemark.c_str()); |
| | | variables.push_back(pVarialble); |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsPassive::loadDataVarialbles(const char* pszFilepath) |
| | | { |
| | | if (pszFilepath == NULL) { |
| | | return -1; |
| | | } |
| | | m_strDataVariableFilepath = pszFilepath; |
| | | m_bDataVariableUtf8 = false; |
| | | m_bDataVariableUtf8Bom = false; |
| | | CFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | const ULONGLONG nLen = file.GetLength(); |
| | | if (nLen == 0) { |
| | | return -1; |
| | | } |
| | | std::string buffer; |
| | | buffer.resize(static_cast<size_t>(nLen)); |
| | | file.Read(buffer.data(), static_cast<UINT>(nLen)); |
| | | file.Close(); |
| | | |
| | | if (hasUtf8Bom(buffer)) { |
| | | m_bDataVariableUtf8 = true; |
| | | m_bDataVariableUtf8Bom = true; |
| | | buffer = buffer.substr(3); |
| | | } |
| | | else if (isLikelyUtf8(buffer)) { |
| | | m_bDataVariableUtf8 = true; |
| | | } |
| | | CStringW content = m_bDataVariableUtf8 ? Utf8ToWide(buffer.c_str()) : AnsiToWide(buffer.c_str()); |
| | | |
| | | // Regex: DVID,DV Name,DV Format,DV Remark |
| | | std::wregex pattern(L"^\\d+,[^,]*,[^,]*,.*"); |
| | | std::vector<SERVO::CDataVariable*> dataVars; |
| | | int index; |
| | | CStringW strLine, strId, strName, strFormat, strRemark; |
| | | std::wstringstream ss(content.GetString()); |
| | | auto narrowFromW = [](const CStringW& s) -> std::string { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return {}; |
| | | std::string out(static_cast<size_t>(need - 1), '\0'); |
| | | WideCharToMultiByte(CP_ACP, 0, s, -1, out.data(), need, nullptr, nullptr); |
| | | return out; |
| | | }; |
| | | std::wstring line; |
| | | while (std::getline(ss, line, L'\n')) { |
| | | strLine = line.c_str(); |
| | | strLine.Trim(); |
| | | if (strLine.IsEmpty()) continue; |
| | | if (!std::regex_match(static_cast<LPCWSTR>(strLine), pattern)) { |
| | | continue; |
| | | } |
| | | index = strLine.Find(L",", 0); |
| | | if (index < 0) continue; |
| | | strId = strLine.Left(index); |
| | | |
| | | strLine = strLine.Right(strLine.GetLength() - index - 1); |
| | | index = strLine.Find(L",", 0); |
| | | if (index < 0) continue; |
| | | strName = strLine.Left(index); |
| | | |
| | | strLine = strLine.Right(strLine.GetLength() - index - 1); |
| | | index = strLine.Find(L",", 0); |
| | | if (index < 0) continue; |
| | | strFormat = strLine.Left(index); |
| | | |
| | | strRemark = strLine.Right(strLine.GetLength() - index - 1); |
| | | strRemark.Replace(L"\\r\\n", L"\r\n"); |
| | | |
| | | std::string sId = narrowFromW(strId); |
| | | std::string sName = narrowFromW(strName); |
| | | std::string sFormat = narrowFromW(strFormat); |
| | | std::string sRemark = narrowFromW(strRemark); |
| | | |
| | | SERVO::CDataVariable* pVarialble = new SERVO::CDataVariable( |
| | | sId.c_str(), |
| | | sName.c_str(), |
| | | sFormat.c_str(), |
| | | sRemark.c_str()); |
| | | dataVars.push_back(pVarialble); |
| | | } |
| | | |
| | | if (!dataVars.empty()) { |
| | | clearAllDataVariabel(); |
| | | for (auto item : dataVars) { |
| | | m_dataVariabels.push_back(item); |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsPassive::loadEquipmentConstants(const char* pszFilepath) |
| | | { |
| | | if (pszFilepath == NULL) return -1; |
| | | m_strEquipmentConstantFilepath = pszFilepath; |
| | | m_bEquipmentConstantUtf8 = false; |
| | | m_bEquipmentConstantUtf8Bom = false; |
| | | |
| | | CFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | const ULONGLONG nLen = file.GetLength(); |
| | | if (nLen == 0) { |
| | | return -1; |
| | | } |
| | | std::string buffer; |
| | | buffer.resize(static_cast<size_t>(nLen)); |
| | | file.Read(buffer.data(), static_cast<UINT>(nLen)); |
| | | file.Close(); |
| | | |
| | | if (hasUtf8Bom(buffer)) { |
| | | m_bEquipmentConstantUtf8 = true; |
| | | m_bEquipmentConstantUtf8Bom = true; |
| | | buffer = buffer.substr(3); |
| | | } |
| | | else if (isLikelyUtf8(buffer)) { |
| | | m_bEquipmentConstantUtf8 = true; |
| | | } |
| | | CStringW content = m_bEquipmentConstantUtf8 ? Utf8ToWide(buffer.c_str()) : AnsiToWide(buffer.c_str()); |
| | | if (content.IsEmpty()) return -1; |
| | | |
| | | std::wregex pattern(L"^\\d+,[^,]*,[^,]*,([^,]*),.*"); |
| | | std::vector<EquipmentConstantEntry> constants; |
| | | CStringW strLine, strId, strName, strFormat, strRemark, strDefault; |
| | | std::wstringstream ss(content.GetString()); |
| | | auto narrowFromW = [](const CStringW& s) -> std::string { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return {}; |
| | | std::string out(static_cast<size_t>(need - 1), '\0'); |
| | | WideCharToMultiByte(CP_ACP, 0, s, -1, out.data(), need, nullptr, nullptr); |
| | | return out; |
| | | }; |
| | | std::wstring line; |
| | | while (std::getline(ss, line, L'\n')) { |
| | | strLine = line.c_str(); |
| | | strLine.Trim(); |
| | | if (strLine.IsEmpty()) continue; |
| | | if (strLine.Find(L"ECID") == 0) continue; // skip header |
| | | if (!std::regex_match(static_cast<LPCWSTR>(strLine), pattern)) { |
| | | continue; |
| | | } |
| | | int last = 0; |
| | | int idx = strLine.Find(L",", last); |
| | | if (idx < 0) continue; |
| | | strId = strLine.Left(idx); |
| | | last = idx + 1; |
| | | |
| | | idx = strLine.Find(L",", last); |
| | | if (idx < 0) continue; |
| | | strName = strLine.Mid(last, idx - last); |
| | | last = idx + 1; |
| | | |
| | | idx = strLine.Find(L",", last); |
| | | if (idx < 0) continue; |
| | | strFormat = strLine.Mid(last, idx - last); |
| | | last = idx + 1; |
| | | |
| | | idx = strLine.Find(L",", last); |
| | | if (idx < 0) continue; |
| | | strRemark = strLine.Mid(last, idx - last); |
| | | last = idx + 1; |
| | | |
| | | strDefault = strLine.Right(strLine.GetLength() - last); |
| | | |
| | | EquipmentConstantEntry entry; |
| | | entry.id = _wtoi(strId); |
| | | entry.name = narrowFromW(strName); |
| | | entry.format = narrowFromW(strFormat); |
| | | entry.remark = narrowFromW(strRemark); |
| | | entry.value = narrowFromW(strDefault); |
| | | constants.push_back(entry); |
| | | } |
| | | |
| | | if (!constants.empty()) { |
| | | m_equipmentConstants = std::move(constants); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | std::vector<SERVO::CVariable*>& CHsmsPassive::getVariables() |
| | | { |
| | | return m_variabels; |
| | | } |
| | | |
| | | std::vector<SERVO::CDataVariable*>& CHsmsPassive::getDataVariables() |
| | | { |
| | | return m_dataVariabels; |
| | | } |
| | | |
| | | unsigned int CHsmsPassive::getMaxVariableId() const |
| | | { |
| | | unsigned int maxId = 0; |
| | | for (auto item : m_variabels) { |
| | | if (item && item->getVarialbleId() > maxId) { |
| | | maxId = item->getVarialbleId(); |
| | | } |
| | | } |
| | | for (auto item : m_dataVariabels) { |
| | | if (item && item->getVarialbleId() > maxId) { |
| | | maxId = item->getVarialbleId(); |
| | | } |
| | | } |
| | | return maxId; |
| | | } |
| | | |
| | | unsigned int CHsmsPassive::getMaxDataVariableId() const |
| | | { |
| | | unsigned int maxId = 0; |
| | | for (auto item : m_variabels) { |
| | | if (item && item->getVarialbleId() > maxId) { |
| | | maxId = item->getVarialbleId(); |
| | | } |
| | | } |
| | | for (auto item : m_dataVariabels) { |
| | | if (item && item->getVarialbleId() > maxId) { |
| | | maxId = item->getVarialbleId(); |
| | | } |
| | | } |
| | | return maxId; |
| | | } |
| | | |
| | | SERVO::CVariable* CHsmsPassive::getVariable(int variableId) |
| | |
| | | return item; |
| | | } |
| | | } |
| | | // try numeric id string |
| | | if (pszName != nullptr && *pszName) { |
| | | const int id = atoi(pszName); |
| | | if (id > 0) { |
| | | return getVariable(id); |
| | | } |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | SERVO::CDataVariable* CHsmsPassive::getDataVariable(int dvid) |
| | | { |
| | | for (auto item : m_dataVariabels) { |
| | | if (item->getVarialbleId() == (unsigned int)dvid) return item; |
| | | } |
| | | return nullptr; |
| | | } |
| | | |
| | | SERVO::CDataVariable* CHsmsPassive::getDataVariable(const char* pszName) |
| | | { |
| | | for (auto item : m_dataVariabels) { |
| | | if (item->getName().compare(pszName) == 0) return item; |
| | | } |
| | | return nullptr; |
| | | } |
| | | |
| | | int CHsmsPassive::getCurrentControlState() |
| | | { |
| | | auto v = getVariable("CurrentControlState"); |
| | | if (v != nullptr) { |
| | | return static_cast<int>(v->getIntValue()); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | bool CHsmsPassive::isHostCommandAllowed() |
| | | { |
| | | // Only allow host control commands in OnlineRemote. |
| | | return getCurrentControlState() == kControlStateOnlineRemote; |
| | | } |
| | | |
| | | void CHsmsPassive::clearAllVariabel() |
| | |
| | | m_variabels.clear(); |
| | | } |
| | | |
| | | void CHsmsPassive::clearAllDataVariabel() |
| | | { |
| | | for (auto item : m_dataVariabels) { |
| | | delete item; |
| | | } |
| | | m_dataVariabels.clear(); |
| | | } |
| | | |
| | | CStringA WideToUtf8(const CStringW& ws) |
| | | { |
| | | int need = WideCharToMultiByte(CP_UTF8, 0, ws, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return ""; |
| | | CStringA out; |
| | | LPSTR buf = out.GetBufferSetLength(need - 1); |
| | | WideCharToMultiByte(CP_UTF8, 0, ws, -1, buf, need, nullptr, nullptr); |
| | | out.ReleaseBuffer(); |
| | | return out; |
| | | } |
| | | |
| | | CStringA WideToAnsi(const CStringW& ws) |
| | | { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, ws, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return ""; |
| | | CStringA out; |
| | | LPSTR buf = out.GetBufferSetLength(need - 1); |
| | | WideCharToMultiByte(CP_ACP, 0, ws, -1, buf, need, nullptr, nullptr); |
| | | out.ReleaseBuffer(); |
| | | return out; |
| | | } |
| | | |
| | | static CStringA AnsiToUtf8(const std::string& s) |
| | | { |
| | | int wlen = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, nullptr, 0); |
| | | if (wlen <= 0) return ""; |
| | | CStringW ws; |
| | | LPWSTR wbuf = ws.GetBufferSetLength(wlen - 1); |
| | | MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, wbuf, wlen); |
| | | ws.ReleaseBuffer(); |
| | | return WideToUtf8(ws); |
| | | } |
| | | |
| | | int CHsmsPassive::deleteVariable(int variableId) |
| | | { |
| | | Lock(); |
| | | auto it = std::find_if(m_variabels.begin(), m_variabels.end(), [=](SERVO::CVariable* v) { |
| | | return v != nullptr && v->getVarialbleId() == variableId; |
| | | }); |
| | | if (it == m_variabels.end()) { |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | delete *it; |
| | | m_variabels.erase(it); |
| | | auto filepath = m_strVariableFilepath; |
| | | Unlock(); |
| | | |
| | | if (filepath.empty()) return -2; |
| | | |
| | | return writeVariablesToFile(filepath); |
| | | } |
| | | |
| | | void CHsmsPassive::setVariableValue(const char* pszName, __int64 value) |
| | | { |
| | | auto v = getVariable(pszName); |
| | | if (v != nullptr) { |
| | | // Protect variable list updates; multiple threads may set SVs. |
| | | Lock(); |
| | | if (auto v = getVariable(pszName)) { |
| | | v->setValue(value); |
| | | } |
| | | else if (auto dv = getDataVariable(pszName)) { |
| | | dv->setValue(value); |
| | | } |
| | | Unlock(); |
| | | } |
| | | |
| | | void CHsmsPassive::setVariableValue(const char* pszName, const char* value) |
| | | { |
| | | auto v = getVariable(pszName); |
| | | if (v != nullptr) { |
| | | Lock(); |
| | | if (auto v = getVariable(pszName)) { |
| | | v->setValue(value); |
| | | } |
| | | else if (auto dv = getDataVariable(pszName)) { |
| | | dv->setValue(value); |
| | | } |
| | | Unlock(); |
| | | } |
| | | |
| | | void CHsmsPassive::setVariableValue(const char* pszName, std::vector<SERVO::CVariable>& vars) |
| | | { |
| | | auto v = getVariable(pszName); |
| | | if (v != nullptr) { |
| | | Lock(); |
| | | if (auto v = getVariable(pszName)) { |
| | | v->setValue(vars); |
| | | } |
| | | else if (auto dv = getDataVariable(pszName)) { |
| | | dv->setValue(vars); |
| | | } |
| | | Unlock(); |
| | | } |
| | | |
| | | void CHsmsPassive::withVariableLock(const std::function<void()>& fn) |
| | | { |
| | | Lock(); |
| | | if (fn) fn(); |
| | | Unlock(); |
| | | } |
| | | |
| | | static bool isValidFormat(const std::string& fmt) |
| | | { |
| | | static const std::set<std::string> allow = { "U1","U2","I2","A20","A50","L" }; |
| | | return allow.count(fmt) > 0; |
| | | } |
| | | |
| | | int CHsmsPassive::addVariable(const char* pszName, const char* pszFormat, const char* pszRemark, int& outId) |
| | | { |
| | | if (pszName == nullptr || pszFormat == nullptr) return -1; |
| | | std::string fmt = pszFormat; |
| | | std::transform(fmt.begin(), fmt.end(), fmt.begin(), ::toupper); |
| | | if (!isValidFormat(fmt)) return -2; |
| | | |
| | | Lock(); |
| | | int maxId = 0; |
| | | for (auto v : m_variabels) { |
| | | if (v != nullptr && static_cast<int>(v->getVarialbleId()) > maxId) { |
| | | maxId = static_cast<int>(v->getVarialbleId()); |
| | | } |
| | | } |
| | | outId = maxId + 1; |
| | | |
| | | SERVO::CVariable* pNew = new SERVO::CVariable(std::to_string(outId).c_str(), pszName, fmt.c_str(), pszRemark ? pszRemark : ""); |
| | | m_variabels.push_back(pNew); |
| | | auto filepath = m_strVariableFilepath; |
| | | Unlock(); |
| | | |
| | | if (filepath.empty()) return -3; |
| | | return writeVariablesToFile(filepath); |
| | | } |
| | | |
| | | int CHsmsPassive::updateVariable(int variableId, const char* pszName, const char* pszFormat, const char* pszRemark) |
| | | { |
| | | if (pszName == nullptr || pszFormat == nullptr) return -1; |
| | | std::string fmt = pszFormat; |
| | | std::transform(fmt.begin(), fmt.end(), fmt.begin(), ::toupper); |
| | | if (!isValidFormat(fmt)) return -2; |
| | | |
| | | Lock(); |
| | | auto it = std::find_if(m_variabels.begin(), m_variabels.end(), [=](SERVO::CVariable* v) { |
| | | return v != nullptr && v->getVarialbleId() == variableId; |
| | | }); |
| | | if (it == m_variabels.end()) { |
| | | Unlock(); |
| | | return -4; |
| | | } |
| | | (*it)->setName(pszName); |
| | | (*it)->setFormat(fmt.c_str()); |
| | | (*it)->setRemark(pszRemark ? pszRemark : ""); |
| | | auto filepath = m_strVariableFilepath; |
| | | Unlock(); |
| | | |
| | | if (filepath.empty()) return -3; |
| | | return writeVariablesToFile(filepath); |
| | | } |
| | | |
| | | int CHsmsPassive::deleteDataVariable(int dvid) |
| | | { |
| | | Lock(); |
| | | auto it = std::find_if(m_dataVariabels.begin(), m_dataVariabels.end(), [=](SERVO::CDataVariable* v) { |
| | | return v != nullptr && v->getVarialbleId() == (unsigned int)dvid; |
| | | }); |
| | | if (it == m_dataVariabels.end()) { |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | delete *it; |
| | | m_dataVariabels.erase(it); |
| | | auto filepath = m_strDataVariableFilepath; |
| | | Unlock(); |
| | | |
| | | if (filepath.empty()) return -2; |
| | | return writeDataVariablesToFile(filepath); |
| | | } |
| | | |
| | | int CHsmsPassive::addDataVariable(const char* pszName, const char* pszFormat, const char* pszRemark, int& outId) |
| | | { |
| | | if (pszName == nullptr || pszFormat == nullptr) return -1; |
| | | std::string fmt = pszFormat; |
| | | std::transform(fmt.begin(), fmt.end(), fmt.begin(), ::toupper); |
| | | if (!isValidFormat(fmt)) return -2; |
| | | |
| | | Lock(); |
| | | int maxId = 0; |
| | | for (auto v : m_dataVariabels) { |
| | | if (v != nullptr && static_cast<int>(v->getVarialbleId()) > maxId) { |
| | | maxId = static_cast<int>(v->getVarialbleId()); |
| | | } |
| | | } |
| | | outId = maxId + 1; |
| | | |
| | | SERVO::CDataVariable* pNew = new SERVO::CDataVariable(std::to_string(outId).c_str(), pszName, fmt.c_str(), pszRemark ? pszRemark : ""); |
| | | m_dataVariabels.push_back(pNew); |
| | | auto filepath = m_strDataVariableFilepath; |
| | | Unlock(); |
| | | |
| | | if (filepath.empty()) return -3; |
| | | return writeDataVariablesToFile(filepath); |
| | | } |
| | | |
| | | int CHsmsPassive::updateDataVariable(int dvid, const char* pszName, const char* pszFormat, const char* pszRemark) |
| | | { |
| | | if (pszName == nullptr || pszFormat == nullptr) return -1; |
| | | std::string fmt = pszFormat; |
| | | std::transform(fmt.begin(), fmt.end(), fmt.begin(), ::toupper); |
| | | if (!isValidFormat(fmt)) return -2; |
| | | |
| | | Lock(); |
| | | auto it = std::find_if(m_dataVariabels.begin(), m_dataVariabels.end(), [=](SERVO::CDataVariable* v) { |
| | | return v != nullptr && v->getVarialbleId() == (unsigned int)dvid; |
| | | }); |
| | | if (it == m_dataVariabels.end()) { |
| | | Unlock(); |
| | | return -4; |
| | | } |
| | | (*it)->setName(pszName); |
| | | (*it)->setFormat(fmt.c_str()); |
| | | (*it)->setRemark(pszRemark ? pszRemark : ""); |
| | | auto filepath = m_strDataVariableFilepath; |
| | | Unlock(); |
| | | |
| | | if (filepath.empty()) return -3; |
| | | return writeDataVariablesToFile(filepath); |
| | | } |
| | | |
| | | int CHsmsPassive::writeVariablesToFile(const std::string& filepath) |
| | | { |
| | | if (filepath.empty()) return -3; |
| | | |
| | | CFile file; |
| | | if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone)) { |
| | | return -3; |
| | | } |
| | | |
| | | // header |
| | | const std::string headerAnsi = "SVID,SV Name,SV Format,SV Remark\r\n"; |
| | | if (m_bVariableUtf8) { |
| | | if (m_bVariableUtf8Bom) { |
| | | const BYTE bom[3] = { 0xEF, 0xBB, 0xBF }; |
| | | file.Write(bom, 3); |
| | | } |
| | | CStringA header = AnsiToUtf8(headerAnsi); |
| | | file.Write(header.GetString(), header.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(headerAnsi.data(), (UINT)headerAnsi.size()); |
| | | } |
| | | |
| | | for (auto v : m_variabels) { |
| | | if (v == nullptr) continue; |
| | | std::string lineAnsi; |
| | | lineAnsi.reserve(256); |
| | | lineAnsi += std::to_string(v->getVarialbleId()); |
| | | lineAnsi.push_back(','); |
| | | lineAnsi += v->getName(); |
| | | lineAnsi.push_back(','); |
| | | lineAnsi += SERVO::CVariable::formatToString(v->getFormat()); |
| | | lineAnsi.push_back(','); |
| | | lineAnsi += v->getRemark(); |
| | | lineAnsi.append("\r\n"); |
| | | |
| | | if (m_bVariableUtf8) { |
| | | CStringA outLine = AnsiToUtf8(lineAnsi); |
| | | file.Write(outLine.GetString(), outLine.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(lineAnsi.data(), (UINT)lineAnsi.size()); |
| | | } |
| | | } |
| | | file.Close(); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsPassive::writeDataVariablesToFile(const std::string& filepath) |
| | | { |
| | | if (filepath.empty()) return -3; |
| | | |
| | | CFile file; |
| | | if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone)) { |
| | | return -3; |
| | | } |
| | | |
| | | const std::string headerAnsi = "DVID,DV Name,DV Format,DV Remark\r\n"; |
| | | if (m_bDataVariableUtf8) { |
| | | if (m_bDataVariableUtf8Bom) { |
| | | const BYTE bom[3] = { 0xEF, 0xBB, 0xBF }; |
| | | file.Write(bom, 3); |
| | | } |
| | | CStringA header = AnsiToUtf8(headerAnsi); |
| | | file.Write(header.GetString(), header.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(headerAnsi.data(), (UINT)headerAnsi.size()); |
| | | } |
| | | |
| | | for (auto v : m_dataVariabels) { |
| | | if (v == nullptr) continue; |
| | | std::string lineAnsi; |
| | | lineAnsi.reserve(256); |
| | | lineAnsi += std::to_string(v->getVarialbleId()); |
| | | lineAnsi.push_back(','); |
| | | lineAnsi += v->getName(); |
| | | lineAnsi.push_back(','); |
| | | lineAnsi += SERVO::CVariable::formatToString(v->getFormat()); |
| | | lineAnsi.push_back(','); |
| | | lineAnsi += v->getRemark(); |
| | | lineAnsi.append("\r\n"); |
| | | |
| | | if (m_bDataVariableUtf8) { |
| | | CStringA outLine = AnsiToUtf8(lineAnsi); |
| | | file.Write(outLine.GetString(), outLine.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(lineAnsi.data(), (UINT)lineAnsi.size()); |
| | | } |
| | | } |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsPassive::loadReports(const char* pszFilepath) |
| | | { |
| | | CStdioFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead)) { |
| | | m_strReportFilepath = pszFilepath; |
| | | m_bReportUtf8 = false; |
| | | m_bReportUtf8Bom = false; |
| | | // å
¼å®¹ UTF-8/BOM 䏿¬å°ç¼ç 读å |
| | | CFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | |
| | | std::regex pattern("^\\d+,\\(\\d+(,\\d+)*\\).*"); // å¹é
以æ°å+éå·å¼å¤´çå符串 |
| | | const ULONGLONG nLen = file.GetLength(); |
| | | if (nLen == 0) { |
| | | return -1; |
| | | } |
| | | |
| | | std::string buffer; |
| | | buffer.resize(static_cast<size_t>(nLen)); |
| | | file.Read(buffer.data(), static_cast<UINT>(nLen)); |
| | | file.Close(); |
| | | |
| | | const unsigned char* bytes = reinterpret_cast<const unsigned char*>(buffer.data()); |
| | | size_t offset = 0; |
| | | CStringW content; |
| | | |
| | | // UTF-8 BOM |
| | | if (nLen >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) { |
| | | offset = 3; |
| | | m_bReportUtf8 = true; |
| | | m_bReportUtf8Bom = true; |
| | | } |
| | | |
| | | // UTF-16 LE BOM |
| | | if (nLen >= 2 && bytes[0] == 0xFF && bytes[1] == 0xFE) { |
| | | const wchar_t* wdata = reinterpret_cast<const wchar_t*>(buffer.data() + 2); |
| | | const size_t wlen = (nLen - 2) / sizeof(wchar_t); |
| | | content.SetString(wdata, static_cast<int>(wlen)); |
| | | } |
| | | // UTF-16 BE BOM |
| | | else if (nLen >= 2 && bytes[0] == 0xFE && bytes[1] == 0xFF) { |
| | | const size_t wlen = (nLen - 2) / sizeof(wchar_t); |
| | | std::wstring temp; |
| | | temp.reserve(wlen); |
| | | for (size_t i = 0; i < wlen; ++i) { |
| | | wchar_t ch = static_cast<wchar_t>(bytes[2 + i * 2] << 8 | bytes[2 + i * 2 + 1]); |
| | | temp.push_back(ch); |
| | | } |
| | | content = temp.c_str(); |
| | | } |
| | | else { |
| | | auto tryUtf8 = [&](size_t off) -> bool { |
| | | int need = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buffer.data() + off, |
| | | static_cast<int>(buffer.size() - off), nullptr, 0); |
| | | if (need <= 0) return false; |
| | | std::wstring temp; |
| | | temp.resize(need); |
| | | MultiByteToWideChar(CP_UTF8, 0, buffer.data() + off, |
| | | static_cast<int>(buffer.size() - off), temp.data(), need); |
| | | content = temp.c_str(); |
| | | m_bReportUtf8 = true; |
| | | return true; |
| | | }; |
| | | |
| | | if (!tryUtf8(offset)) { |
| | | int need = MultiByteToWideChar(CP_ACP, 0, buffer.data(), static_cast<int>(buffer.size()), nullptr, 0); |
| | | if (need > 0) { |
| | | std::wstring temp; |
| | | temp.resize(need); |
| | | MultiByteToWideChar(CP_ACP, 0, buffer.data(), static_cast<int>(buffer.size()), temp.data(), need); |
| | | content = temp.c_str(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (content.IsEmpty()) { |
| | | return -1; |
| | | } |
| | | |
| | | std::wregex pattern(L"^\\d+,\\(\\d+(,\\d+)*\\).*"); // å¹é
以æ°å+éå·å¼å¤´çå符串 |
| | | std::vector<SERVO::CReport*> reports; |
| | | int index; |
| | | CString strLine, strVariable; |
| | | CString strId; |
| | | while (file.ReadString(strLine)) { |
| | | if (!std::regex_match((LPTSTR)(LPCTSTR)strLine, pattern)) { |
| | | CStringW strLine, strVariable; |
| | | CStringW strId; |
| | | std::wstringstream ss(content.GetString()); |
| | | auto narrowFromW = [](const CStringW& s) -> std::string { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return {}; |
| | | std::string out(static_cast<size_t>(need - 1), '\0'); |
| | | WideCharToMultiByte(CP_ACP, 0, s, -1, out.data(), need, nullptr, nullptr); |
| | | return out; |
| | | }; |
| | | std::wstring line; |
| | | while (std::getline(ss, line, L'\n')) { |
| | | strLine = line.c_str(); |
| | | strLine.Trim(); |
| | | if (strLine.IsEmpty()) continue; |
| | | if (!std::regex_match(static_cast<LPCWSTR>(strLine), pattern)) { |
| | | continue; |
| | | } |
| | | |
| | | index = strLine.Find(",", 0); |
| | | index = strLine.Find(L",", 0); |
| | | if (index < 0) continue; |
| | | strId = strLine.Left(index); |
| | | strVariable = strLine.Right(strLine.GetLength() - index - 1); |
| | | strVariable.Delete(0); |
| | | strVariable.Delete(strVariable.GetLength() - 1); |
| | | auto vids = parseVidList(strVariable); |
| | | CString strVariableA(narrowFromW(strVariable).c_str()); |
| | | auto vids = parseVidList(strVariableA); |
| | | |
| | | SERVO::CReport* pReport = new SERVO::CReport(atoi((LPTSTR)(LPCTSTR)strId), vids); |
| | | SERVO::CReport* pReport = new SERVO::CReport(_wtoi(strId), vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable(vid); |
| | | if (pVariable == nullptr) { |
| | | pVariable = getDataVariable(vid); |
| | | } |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | } |
| | |
| | | } |
| | | |
| | | |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | |
| | | std::vector<SERVO::CReport*>& CHsmsPassive::getReports() |
| | | { |
| | | return m_reports; |
| | | } |
| | | |
| | | unsigned int CHsmsPassive::getMaxReportId() const |
| | | { |
| | | unsigned int maxId = 0; |
| | | for (auto item : m_reports) { |
| | | if (item && item->getReportId() > maxId) { |
| | | maxId = item->getReportId(); |
| | | } |
| | | } |
| | | return maxId; |
| | | } |
| | | |
| | | SERVO::CReport* CHsmsPassive::getReport(int rptid) |
| | |
| | | return false; |
| | | } |
| | | |
| | | void CHsmsPassive::clearAllReport() |
| | | int CHsmsPassive::deleteReport(int rptid) |
| | | { |
| | | LOGI("<CHsmsPassive>deleteReport enter"); |
| | | if (!removeReport(rptid)) { |
| | | return -1; |
| | | } |
| | | LOGI("<CHsmsPassive>delete Report. rptid=%d", rptid); |
| | | |
| | | return writeReportsToFile(m_strReportFilepath); |
| | | } |
| | | |
| | | int CHsmsPassive::addReport(int rptid, const std::vector<unsigned int>& vids) |
| | | { |
| | | if (getReport(rptid) != nullptr) { |
| | | return -1; |
| | | } |
| | | SERVO::CReport* pReport = new SERVO::CReport(rptid, vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable((int)vid); |
| | | if (pVariable == nullptr) { |
| | | pVariable = getDataVariable((int)vid); |
| | | } |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | } |
| | | } |
| | | m_reports.push_back(pReport); |
| | | return writeReportsToFile(m_strReportFilepath); |
| | | } |
| | | |
| | | int CHsmsPassive::updateReport(int rptid, const std::vector<unsigned int>& vids) |
| | | { |
| | | for (auto iter = m_reports.begin(); iter != m_reports.end(); ++iter) { |
| | | if ((*iter)->getReportId() == rptid) { |
| | | delete (*iter); |
| | | SERVO::CReport* pReport = new SERVO::CReport(rptid, vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable((int)vid); |
| | | if (pVariable == nullptr) { |
| | | pVariable = getDataVariable((int)vid); |
| | | } |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | } |
| | | } |
| | | *iter = pReport; |
| | | return writeReportsToFile(m_strReportFilepath); |
| | | } |
| | | } |
| | | return -1; |
| | | } |
| | | |
| | | void CHsmsPassive::clearAllReport(BOOL bSave/* = FALSE*/) |
| | | { |
| | | LOGI("<CHsmsPassive>clearAllReport enter"); |
| | | for (auto item : m_reports) { |
| | | delete item; |
| | | } |
| | | m_reports.clear(); |
| | | |
| | | if(bSave) |
| | | writeReportsToFile(m_strReportFilepath); |
| | | } |
| | | |
| | | int CHsmsPassive::writeReportsToFile(const std::string& filepath) |
| | | { |
| | | if (filepath.empty()) return -1; |
| | | |
| | | CFile file; |
| | | if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite)) { |
| | | return -1; |
| | | } |
| | | |
| | | if (m_bReportUtf8 && m_bReportUtf8Bom) { |
| | | const BYTE bom[3] = { 0xEF, 0xBB, 0xBF }; |
| | | file.Write(bom, 3); |
| | | } |
| | | |
| | | // header |
| | | const std::string headerAnsi = "RPTID,(VID1,VID2,...)\r\n"; |
| | | if (m_bReportUtf8) { |
| | | CStringA header = AnsiToUtf8(headerAnsi); |
| | | file.Write(header.GetString(), header.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(headerAnsi.data(), (UINT)headerAnsi.size()); |
| | | } |
| | | |
| | | for (auto rpt : m_reports) { |
| | | if (rpt == nullptr) continue; |
| | | std::string line; |
| | | line.reserve(64); |
| | | line += std::to_string(rpt->getReportId()); |
| | | line += ",("; |
| | | |
| | | const auto& vids = rpt->getVids(); |
| | | for (size_t i = 0; i < vids.size(); ++i) { |
| | | line += std::to_string(vids[i]); |
| | | if (i + 1 < vids.size()) { |
| | | line.push_back(','); |
| | | } |
| | | } |
| | | line += ")\r\n"; |
| | | |
| | | if (m_bReportUtf8) { |
| | | CStringA out = AnsiToUtf8(line); |
| | | file.Write(out.GetString(), out.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(line.data(), (UINT)line.size()); |
| | | } |
| | | } |
| | | |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsPassive::loadCollectionEvents(const char* pszFilepath) |
| | | { |
| | | CStdioFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead)) { |
| | | m_strCollectionEventFilepath = pszFilepath; |
| | | m_bCollectionUtf8 = false; |
| | | m_bCollectionUtf8Bom = false; |
| | | CFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | |
| | | std::regex pattern("^\\d+,[^,]*,[^,]*,\\(\\d+(,\\d+)*\\).*"); // å¹é
以æ°å+éå·å¼å¤´çå符串 |
| | | const ULONGLONG nLen = file.GetLength(); |
| | | if (nLen == 0) { |
| | | return -1; |
| | | } |
| | | |
| | | std::string buffer; |
| | | buffer.resize(static_cast<size_t>(nLen)); |
| | | file.Read(buffer.data(), static_cast<UINT>(nLen)); |
| | | file.Close(); |
| | | |
| | | const unsigned char* bytes = reinterpret_cast<const unsigned char*>(buffer.data()); |
| | | size_t offset = 0; |
| | | CStringW content; |
| | | |
| | | // UTF-8 BOM |
| | | if (nLen >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) { |
| | | offset = 3; |
| | | m_bCollectionUtf8 = true; |
| | | m_bCollectionUtf8Bom = true; |
| | | } |
| | | |
| | | // UTF-16 LE BOM |
| | | if (nLen >= 2 && bytes[0] == 0xFF && bytes[1] == 0xFE) { |
| | | const wchar_t* wdata = reinterpret_cast<const wchar_t*>(buffer.data() + 2); |
| | | const size_t wlen = (nLen - 2) / sizeof(wchar_t); |
| | | content.SetString(wdata, static_cast<int>(wlen)); |
| | | } |
| | | // UTF-16 BE BOM |
| | | else if (nLen >= 2 && bytes[0] == 0xFE && bytes[1] == 0xFF) { |
| | | const size_t wlen = (nLen - 2) / sizeof(wchar_t); |
| | | std::wstring temp; |
| | | temp.reserve(wlen); |
| | | for (size_t i = 0; i < wlen; ++i) { |
| | | wchar_t ch = static_cast<wchar_t>(bytes[2 + i * 2] << 8 | bytes[2 + i * 2 + 1]); |
| | | temp.push_back(ch); |
| | | } |
| | | content = temp.c_str(); |
| | | } |
| | | else { |
| | | auto tryUtf8 = [&](size_t off) -> bool { |
| | | int need = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buffer.data() + off, |
| | | static_cast<int>(buffer.size() - off), nullptr, 0); |
| | | if (need <= 0) return false; |
| | | std::wstring temp; |
| | | temp.resize(need); |
| | | MultiByteToWideChar(CP_UTF8, 0, buffer.data() + off, |
| | | static_cast<int>(buffer.size() - off), temp.data(), need); |
| | | content = temp.c_str(); |
| | | m_bCollectionUtf8 = true; |
| | | return true; |
| | | }; |
| | | |
| | | if (!tryUtf8(offset)) { |
| | | int need = MultiByteToWideChar(CP_ACP, 0, buffer.data(), static_cast<int>(buffer.size()), nullptr, 0); |
| | | if (need > 0) { |
| | | std::wstring temp; |
| | | temp.resize(need); |
| | | MultiByteToWideChar(CP_ACP, 0, buffer.data(), static_cast<int>(buffer.size()), temp.data(), need); |
| | | content = temp.c_str(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (content.IsEmpty()) { |
| | | return -1; |
| | | } |
| | | |
| | | // å
许 Attached RPTID 为空ï¼() |
| | | std::wregex pattern(L"^\\d+,[^,]*,[^,]*,\\(\\d*(,\\d+)*\\).*"); // å¹é
以æ°å+éå·å¼å¤´çå符串 |
| | | std::vector<SERVO::CCollectionEvent*> events; |
| | | int index, last; |
| | | CString strLine, strRPTIDs; |
| | | CString strId, strName, strDescription; |
| | | while (file.ReadString(strLine)) { |
| | | if (!std::regex_match((LPTSTR)(LPCTSTR)strLine, pattern)) { |
| | | CStringW strLine, strRPTIDs; |
| | | CStringW strId, strName, strDescription; |
| | | std::wstringstream ss(content.GetString()); |
| | | auto narrowFromW = [](const CStringW& s) -> std::string { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return {}; |
| | | std::string out(static_cast<size_t>(need - 1), '\0'); |
| | | WideCharToMultiByte(CP_ACP, 0, s, -1, out.data(), need, nullptr, nullptr); |
| | | return out; |
| | | }; |
| | | std::wstring line; |
| | | while (std::getline(ss, line, L'\n')) { |
| | | strLine = line.c_str(); |
| | | strLine.Trim(); |
| | | if (strLine.IsEmpty()) continue; |
| | | if (!std::regex_match(static_cast<LPCWSTR>(strLine), pattern)) { |
| | | continue; |
| | | } |
| | | |
| | | last = 0; |
| | | index = strLine.Find(",", last); |
| | | index = strLine.Find(L",", last); |
| | | if (index < 0) continue; |
| | | strId = strLine.Left(index); |
| | | last = index + 1; |
| | | |
| | | index = strLine.Find(",", last); |
| | | index = strLine.Find(L",", last); |
| | | if (index < 0) continue; |
| | | strName = strLine.Mid(last, index - last); |
| | | last = index + 1; |
| | | |
| | | index = strLine.Find(",", last); |
| | | index = strLine.Find(L",", last); |
| | | if (index < 0) continue; |
| | | strDescription = strLine.Mid(last, index - last); |
| | | strRPTIDs = strLine.Right(strLine.GetLength() - index - 1); |
| | | strRPTIDs.Delete(0); |
| | | strRPTIDs.Delete(strRPTIDs.GetLength() - 1); |
| | | auto prtids = parseVidList(strRPTIDs); |
| | | CString strRPTIDsA(narrowFromW(strRPTIDs).c_str()); |
| | | auto prtids = parseVidList(strRPTIDsA); |
| | | |
| | | std::string sName = narrowFromW(strName); |
| | | std::string sDesc = narrowFromW(strDescription); |
| | | |
| | | SERVO::CCollectionEvent* pEvent = new SERVO::CCollectionEvent( |
| | | atoi(strId), (LPTSTR)(LPCTSTR)strName, (LPTSTR)(LPCTSTR)strDescription, prtids); |
| | | _wtoi(strId), sName.c_str(), sDesc.c_str(), prtids); |
| | | for (auto rptid : prtids) { |
| | | SERVO::CReport* pReport = getReport(rptid); |
| | | if (pReport != nullptr) { |
| | |
| | | m_collectionEvents.push_back(item); |
| | | } |
| | | } |
| | | |
| | | |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | |
| | | std::vector<SERVO::CCollectionEvent*>& CHsmsPassive::getCollectionEvents() |
| | | { |
| | | return m_collectionEvents; |
| | | } |
| | | |
| | | unsigned int CHsmsPassive::getMaxCollectionEventId() const |
| | | { |
| | | unsigned int maxId = 0; |
| | | for (auto item : m_collectionEvents) { |
| | | if (item && item->getEventId() > maxId) { |
| | | maxId = item->getEventId(); |
| | | } |
| | | } |
| | | return maxId; |
| | | } |
| | | |
| | | int CHsmsPassive::deleteCollectionEvent(unsigned short CEID) |
| | | { |
| | | for (auto iter = m_collectionEvents.begin(); iter != m_collectionEvents.end(); ++iter) { |
| | | if ((*iter)->getEventId() == CEID) { |
| | | delete (*iter); |
| | | m_collectionEvents.erase(iter); |
| | | return writeCollectionEventsToFile(m_strCollectionEventFilepath); |
| | | } |
| | | } |
| | | return -1; |
| | | } |
| | | |
| | | int CHsmsPassive::addCollectionEvent(unsigned int CEID, const char* name, const char* desc, const std::vector<unsigned int>& rptids) |
| | | { |
| | | if (getEvent((unsigned short)CEID) != nullptr) { |
| | | return -1; |
| | | } |
| | | auto* pEvent = new SERVO::CCollectionEvent(CEID, name, desc, const_cast<std::vector<unsigned int>&>(rptids)); |
| | | for (auto rptid : rptids) { |
| | | SERVO::CReport* pReport = getReport((int)rptid); |
| | | if (pReport != nullptr) { |
| | | pEvent->addReport(pReport); |
| | | } |
| | | } |
| | | m_collectionEvents.push_back(pEvent); |
| | | return writeCollectionEventsToFile(m_strCollectionEventFilepath); |
| | | } |
| | | |
| | | int CHsmsPassive::updateCollectionEvent(unsigned int CEID, const char* name, const char* desc, const std::vector<unsigned int>& rptids) |
| | | { |
| | | for (auto iter = m_collectionEvents.begin(); iter != m_collectionEvents.end(); ++iter) { |
| | | if ((*iter)->getEventId() == CEID) { |
| | | delete (*iter); |
| | | auto* pEvent = new SERVO::CCollectionEvent(CEID, name, desc, const_cast<std::vector<unsigned int>&>(rptids)); |
| | | for (auto rptid : rptids) { |
| | | SERVO::CReport* pReport = getReport((int)rptid); |
| | | if (pReport != nullptr) { |
| | | pEvent->addReport(pReport); |
| | | } |
| | | } |
| | | *iter = pEvent; |
| | | return writeCollectionEventsToFile(m_strCollectionEventFilepath); |
| | | } |
| | | } |
| | | return -1; |
| | | } |
| | | |
| | | void CHsmsPassive::clearAllCollectionEvent() |
| | |
| | | return result; |
| | | } |
| | | |
| | | int CHsmsPassive::writeCollectionEventsToFile(const std::string& filepath) |
| | | { |
| | | if (filepath.empty()) return -1; |
| | | |
| | | CFile file; |
| | | if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite)) { |
| | | return -1; |
| | | } |
| | | |
| | | if (m_bCollectionUtf8 && m_bCollectionUtf8Bom) { |
| | | const BYTE bom[3] = { 0xEF, 0xBB, 0xBF }; |
| | | file.Write(bom, 3); |
| | | } |
| | | |
| | | const std::string headerAnsi = "CEID,CE Name,Descriptions,Attached RPTID\r\n"; |
| | | if (m_bCollectionUtf8) { |
| | | CStringA header = AnsiToUtf8(headerAnsi); |
| | | file.Write(header.GetString(), header.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(headerAnsi.data(), (UINT)headerAnsi.size()); |
| | | } |
| | | |
| | | for (auto ev : m_collectionEvents) { |
| | | if (ev == nullptr) continue; |
| | | std::string line; |
| | | line.reserve(128); |
| | | line += std::to_string(ev->getEventId()); |
| | | line.push_back(','); |
| | | line += ev->getName(); |
| | | line.push_back(','); |
| | | line += ev->getDescription(); |
| | | line.push_back(','); |
| | | line.push_back('('); |
| | | auto rptIds = ev->getReportIds(); |
| | | for (size_t i = 0; i < rptIds.size(); ++i) { |
| | | line += std::to_string(rptIds[i]); |
| | | if (i + 1 < rptIds.size()) { |
| | | line.push_back(','); |
| | | } |
| | | } |
| | | line += ")\r\n"; |
| | | |
| | | if (m_bCollectionUtf8) { |
| | | CStringA out = AnsiToUtf8(line); |
| | | file.Write(out.GetString(), out.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(line.data(), (UINT)line.size()); |
| | | } |
| | | } |
| | | |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsPassive::init(CModel* pModel, const char* pszName, unsigned int port) |
| | | { |
| | | m_pModel = pModel; |
| | |
| | | */ |
| | | }; |
| | | auto onRecvSysMessage = [&](void* pFrom, IMessage* pMessage) -> void { |
| | | LOGI("<HSMS>onRecvSysMessage:sessionId:%d, sType:%d systemBytes:%d", |
| | | LOGI("<HSMS>[Received]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | onRecvMsg(pMessage); |
| | | if (MSG_LINKTEST_REQ == pMessage->getHeader()->sType) { |
| | |
| | | HEADER* pHeader = pMessage->getHeader(); |
| | | int nStream = (pHeader->stream & 0x7F); |
| | | |
| | | LOGI("<HSMS>æ¶å°æ¶æ¯ S%dF%d", nStream, pHeader->function); |
| | | LogSecsMessageBrief("<HSMS>[Received]", pMessage); |
| | | if (nStream == 1 && pHeader->function == 1) { |
| | | // S1F1 |
| | | replyAreYouThere(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 3) { |
| | | replySelectedEquipmentStatusData(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 11) { |
| | | replyStatusVariableNamelistRequest(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 21) { |
| | | replyDataVariableNamelistRequest(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 23) { |
| | | replyCollectionEventNamelistRequest(pMessage); |
| | | } |
| | | else if (nStream == 1 && pHeader->function == 13) { |
| | | replyEstablishCommunications(pMessage); |
| | |
| | | else if (nStream == 7 && pHeader->function == 19) { |
| | | replyQueryPPIDList(pMessage); |
| | | } |
| | | else if (nStream == 7 && pHeader->function == 17) { |
| | | replyDeletePPID(pMessage); |
| | | } |
| | | else if (nStream == 7 && pHeader->function == 5) { |
| | | replyProcessProgramRequest(pMessage); |
| | | } |
| | | else if (nStream == 10 && pHeader->function == 3) { |
| | | replyTerminalDisplay(pMessage); |
| | | } |
| | |
| | | return -1; |
| | | } |
| | | |
| | | int nBufSize = file.GetLength(); |
| | | ULONGLONG len = file.GetLength(); |
| | | if (len > INT_MAX) { |
| | | file.Close(); |
| | | return -1; |
| | | } |
| | | int nBufSize = static_cast<int>(len); |
| | | char* pszBuffer = new char[nBufSize]; |
| | | file.Read(pszBuffer, nBufSize); |
| | | file.Close(); |
| | |
| | | int CHsmsPassive::serialize(char* pszBuffer, int nBufferSize) |
| | | { |
| | | int index = 0; |
| | | const auto calcSpoolCfgSize = [&]() -> int { |
| | | // magic(4) + ver(2) + enabled(1) + mapSize(4) + entries... |
| | | int sz = 0; |
| | | sz += 4; // 'SPOL' |
| | | sz += 2; // version |
| | | sz += 1; // enabled |
| | | sz += 4; // map size |
| | | for (const auto& kv : m_spoolBlacklistByStream) { |
| | | sz += 2; // streamId (U16) |
| | | sz += 4; // fn count (U32) |
| | | sz += static_cast<int>(kv.second.size()) * 2; // fn ids (U16 each) |
| | | } |
| | | return sz; |
| | | }; |
| | | if (pszBuffer == nullptr) { |
| | | index += sizeof(int); |
| | | for (auto item : m_listActionSpooling) { |
| | | index += item->serialize(pszBuffer, nBufferSize); |
| | | if (item == nullptr || item->getSendMessage() == nullptr) { |
| | | LOGE("<HSMS>skip spooling item: null send message"); |
| | | continue; |
| | | } |
| | | int nRet = item->serialize(nullptr, 0); |
| | | if (nRet <= 0) { |
| | | LOGE("<HSMS>skip spooling item: serialize failed"); |
| | | continue; |
| | | } |
| | | index += nRet; |
| | | } |
| | | |
| | | index += calcSpoolCfgSize(); |
| | | |
| | | return index; |
| | | } |
| | | else { |
| | | int nTemp, nRet; |
| | | int nTemp = 0; |
| | | int nRet = 0; |
| | | |
| | | nTemp = (int)m_listActionSpooling.size(); |
| | | for (auto item : m_listActionSpooling) { |
| | | if (item == nullptr || item->getSendMessage() == nullptr) { |
| | | continue; |
| | | } |
| | | if (item->serialize(nullptr, 0) > 0) { |
| | | ++nTemp; |
| | | } |
| | | } |
| | | |
| | | memcpy(&pszBuffer[index], &nTemp, sizeof(int)); |
| | | index += sizeof(int); |
| | | |
| | | for (auto item : m_listActionSpooling) { |
| | | if (item == nullptr || item->getSendMessage() == nullptr) { |
| | | LOGE("<HSMS>skip spooling item: null send message"); |
| | | continue; |
| | | } |
| | | nRet = item->serialize(&pszBuffer[index], nBufferSize); |
| | | if (nRet <= 0) break; |
| | | if (nRet <= 0) { |
| | | LOGE("<HSMS>skip spooling item: serialize failed"); |
| | | continue; |
| | | } |
| | | index += nRet; |
| | | } |
| | | |
| | | // Append spooling config (backward compatible via magic+version) |
| | | auto writeU32 = [&](uint32_t v) { |
| | | memcpy(&pszBuffer[index], &v, sizeof(v)); |
| | | index += sizeof(v); |
| | | }; |
| | | auto writeU16 = [&](uint16_t v) { |
| | | memcpy(&pszBuffer[index], &v, sizeof(v)); |
| | | index += sizeof(v); |
| | | }; |
| | | auto writeU8 = [&](uint8_t v) { |
| | | memcpy(&pszBuffer[index], &v, sizeof(v)); |
| | | index += sizeof(v); |
| | | }; |
| | | |
| | | const uint32_t magic = 0x4C4F5053; // 'SPOL' little-endian |
| | | writeU32(magic); |
| | | writeU16(1); // version |
| | | writeU8(m_spoolingEnabled ? 1 : 0); |
| | | writeU32(static_cast<uint32_t>(m_spoolBlacklistByStream.size())); |
| | | for (const auto& kv : m_spoolBlacklistByStream) { |
| | | writeU16(static_cast<uint16_t>(kv.first)); |
| | | writeU32(static_cast<uint32_t>(kv.second.size())); |
| | | for (const auto& fn : kv.second) { |
| | | writeU16(static_cast<uint16_t>(fn)); |
| | | } |
| | | } |
| | | |
| | | return index; |
| | |
| | | for (int i = 0; i < nTemp; i++) { |
| | | CHsmsAction* pAction = new CHsmsAction(); |
| | | nRet = pAction->unserialize(&pszBuffer[index], nBufferSize - index); |
| | | if (nRet <= 0) break; |
| | | if (nRet <= 0 || pAction->getSendMessage() == nullptr) { |
| | | delete pAction; |
| | | break; |
| | | } |
| | | index += nRet; |
| | | m_listActionSpooling.push_back(pAction); |
| | | } |
| | | |
| | | return index + nRet; |
| | | // Parse optional spooling config tail (magic+version). If absent, keep defaults. |
| | | const auto remaining = nBufferSize - index; |
| | | if (remaining >= 4) { |
| | | uint32_t magic = 0; |
| | | memcpy(&magic, &pszBuffer[index], sizeof(magic)); |
| | | if (magic == 0x4C4F5053) { // 'SPOL' |
| | | index += 4; |
| | | if (nBufferSize - index >= 2 + 1 + 4) { |
| | | uint16_t ver = 0; |
| | | memcpy(&ver, &pszBuffer[index], sizeof(ver)); |
| | | index += 2; |
| | | if (ver >= 1) { |
| | | uint8_t enabled = 1; |
| | | memcpy(&enabled, &pszBuffer[index], sizeof(enabled)); |
| | | index += 1; |
| | | m_spoolingEnabled = (enabled != 0); |
| | | |
| | | uint32_t mapSize = 0; |
| | | memcpy(&mapSize, &pszBuffer[index], sizeof(mapSize)); |
| | | index += 4; |
| | | |
| | | m_spoolBlacklistByStream.clear(); |
| | | for (uint32_t mi = 0; mi < mapSize; ++mi) { |
| | | if (nBufferSize - index < 2 + 4) break; |
| | | uint16_t streamId = 0; |
| | | memcpy(&streamId, &pszBuffer[index], sizeof(streamId)); |
| | | index += 2; |
| | | uint32_t fnCount = 0; |
| | | memcpy(&fnCount, &pszBuffer[index], sizeof(fnCount)); |
| | | index += 4; |
| | | |
| | | auto& setRef = m_spoolBlacklistByStream[streamId]; |
| | | setRef.clear(); |
| | | for (uint32_t fi = 0; fi < fnCount; ++fi) { |
| | | if (nBufferSize - index < 2) break; |
| | | uint16_t fn = 0; |
| | | memcpy(&fn, &pszBuffer[index], sizeof(fn)); |
| | | index += 2; |
| | | setRef.insert(fn); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return index; |
| | | } |
| | | |
| | | unsigned CHsmsPassive::OnCimWork() |
| | |
| | | Unlock(); |
| | | |
| | | while (!list.empty()) { |
| | | CHsmsAction* pAction = nullptr; |
| | | Lock(); |
| | | CHsmsAction* pAction = list.front(); |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | m_listActionSpooling.push_back(pAction); |
| | | Unlock(); |
| | | continue; |
| | | } |
| | | pAction = list.front(); |
| | | Unlock(); |
| | | list.pop_front(); |
| | | |
| | | Lock(); |
| | | const bool selected = (m_pPassive != NULL && STATE::SELECTED == m_pPassive->getState()); |
| | | Unlock(); |
| | | if (!selected) { |
| | | IMessage* pMsg = pAction->getSendMessage(); |
| | | if (pMsg == NULL) { |
| | | LOGE("<HSMS>spooling drop: null send message"); |
| | | delete pAction; |
| | | continue; |
| | | } |
| | | uint8_t streamId = 0; |
| | | uint8_t functionId = 0; |
| | | if (pMsg && pMsg->getHeader()) { |
| | | streamId = static_cast<uint8_t>(pMsg->getHeader()->stream & 0x7F); |
| | | functionId = static_cast<uint8_t>(pMsg->getHeader()->function & 0xFF); |
| | | } |
| | | if (shouldSpool(streamId, functionId)) { |
| | | Lock(); |
| | | m_listActionSpooling.push_back(pAction); |
| | | Unlock(); |
| | | } |
| | | else { |
| | | LOGI("<HSMS>spooling disabled for S%dF%d, drop action", (int)streamId, (int)functionId); |
| | | delete pAction; |
| | | } |
| | | continue; |
| | | } |
| | | TRACE("OnCimWork 004.\n"); |
| | | |
| | | if (pAction->isNeedWaitReply()) { |
| | | // 妿éè¦çå¾
åå¤ |
| | | IMessage* pMessage = pAction->getSendMessage(); |
| | | if (pMessage == NULL) { |
| | | LOGE("<HSMS>drop action: null send message"); |
| | | delete pAction; |
| | | continue; |
| | | } |
| | | Lock(); |
| | | m_pActiveAction = pAction; |
| | | IMessage* pMessage = pAction->getSendMessage(); |
| | | Unlock(); |
| | | |
| | | ASSERT(pMessage); |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS> [SEND] SysByte=%u sessionId:%d", pMessage->getHeader()->systemBytes, pMessage->getHeader()->sessionId); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | |
| | | int nRet = WaitForSingleObject(pAction->getEvent(), pAction->getTimeout() * 1000); |
| | | if (nRet == WAIT_TIMEOUT) { |
| | |
| | | Unlock(); |
| | | } |
| | | else { |
| | | IMessage* pMessage = pAction->getSendMessage(); |
| | | if (pMessage == NULL) { |
| | | LOGE("<HSMS>drop action: null send message"); |
| | | delete pAction; |
| | | continue; |
| | | } |
| | | Lock(); |
| | | m_listActionSent.push_back(pAction); |
| | | IMessage* pMessage = pAction->getSendMessage(); |
| | | Unlock(); |
| | | |
| | | ASSERT(pMessage); |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS> [SEND] SysByte=%u sessionId:%d", pMessage->getHeader()->systemBytes, pMessage->getHeader()->sessionId); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | |
| | | } |
| | | } |
| | |
| | | ISECS2Item* pItem = pMessage->getBody(); |
| | | pItem->setBinary((const char*)&ack, 1, pszAckName); |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SECS Msg SEND]S%dF%d (SysByte=%u)", s, f, systemBytes); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | } |
| | | |
| | |
| | | |
| | | Lock(); |
| | | CHsmsAction* pAction = new CHsmsAction(ACTION_HELLO, FALSE, m_nActionTimeout); |
| | | m_listAction.push_back(pAction); |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 1, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | | if (HSMS_Create1Message(pMessage, m_nSessionId, 1 | REPLY, 1, ++m_nSystemByte) != 0 || pMessage == NULL) { |
| | | LOGE("<HSMS>S1F1 create message failed"); |
| | | delete pAction; |
| | | Unlock(); |
| | | return ER_CREATED_MESSAGE; |
| | | } |
| | | pAction->setSendMessage(pMessage); |
| | | m_listAction.push_back(pAction); |
| | | |
| | | SetEvent(m_hCimWorkEvent); |
| | | Unlock(); |
| | |
| | | pItem->addItem(m_strEquipmentModelType.c_str(), "MDLN"); |
| | | pItem->addItem(m_strSoftRev.c_str(), "SOFTREV"); |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SECS Msg SEND]S1F2 (SysByte=%u)", pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | |
| | | pList->addItem(m_strEquipmentModelType.c_str(), "MDLN"); |
| | | pList->addItem(m_strSoftRev.c_str(), "SOFTREV"); |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SECS Msg SEND]%s", pMessage->toString()); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | |
| | | ASSERT(pMessage); |
| | | |
| | | unsigned char SVU1 = 0; |
| | | unsigned int SVID = 0; |
| | | unsigned short 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)) { |
| | | if (!pBody->getSubItemU2(0, SVID)) { |
| | | // also accept I2 or U4 to be tolerant with host implementations |
| | | if (!pBody->getSubItemI2(0, (short&)SVID)) { |
| | | unsigned int svidU4 = 0; |
| | | if (!pBody->getSubItemU4(0, svidU4)) { |
| | | pMessage->getBody()->addU1Item(SVU1, "SV"); |
| | | goto MYREPLY; |
| | | } |
| | | SVID = static_cast<unsigned short>(svidU4); |
| | | } |
| | | } |
| | | |
| | | SERVO::CVariable* pVariable = getVariable(SVID); |
| | | SERVO::CVariable* pVariable = getVariable((int)SVID); |
| | | if (pVariable == nullptr) { |
| | | pMessage->getBody()->addU1Item(SVU1, "SV"); |
| | | goto MYREPLY; |
| | |
| | | |
| | | MYREPLY: |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SECS Msg SEND]%s", pMessage->toString()); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | // S1F11 |
| | | int CHsmsPassive::replyStatusVariableNamelistRequest(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | std::vector<unsigned short> reqIds; |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | if (pBody != nullptr && pBody->getType() == SITYPE::L) { |
| | | const int sz = pBody->getSubItemSize(); |
| | | for (int i = 0; i < sz; ++i) { |
| | | unsigned short id = 0; |
| | | if (pBody->getSubItemU2(i, id)) { |
| | | reqIds.push_back(id); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Build response list items: {L:3 SVID, SVNAME, UNITS} |
| | | std::vector<unsigned short> svids; |
| | | std::set<unsigned short> requested(reqIds.begin(), reqIds.end()); |
| | | Lock(); |
| | | if (reqIds.empty()) { |
| | | for (auto v : m_variabels) { |
| | | svids.push_back(static_cast<unsigned short>(v->getVarialbleId())); |
| | | } |
| | | } |
| | | else { |
| | | // include requested IDs (existing + unknown marker) |
| | | for (auto id : requested) { |
| | | svids.push_back(id); |
| | | } |
| | | } |
| | | Unlock(); |
| | | |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 12, pRecv->getHeader()->systemBytes); |
| | | ASSERT(pMessage); |
| | | |
| | | ISECS2Item* pList = pMessage->getBody(); // Body is L[n] of {SVID, SVNAME, UNITS} |
| | | for (auto id : svids) { |
| | | ISECS2Item* pEntry = pList->addItem(); |
| | | pEntry->addU2Item(id, "SVID"); |
| | | SERVO::CVariable* v = getVariable((int)id); |
| | | if (v != nullptr) { |
| | | pEntry->addItem(v->getName().c_str(), "SVNAME"); |
| | | // Use remark as UNITS if provided; empty string if none. |
| | | pEntry->addItem(v->getRemark().c_str(), "UNITS"); |
| | | } |
| | | else { |
| | | // Unknown SVID: A:0 for name/units |
| | | pEntry->addItem("", "SVNAME"); |
| | | pEntry->addItem("", "UNITS"); |
| | | } |
| | | } |
| | | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return ER_NOERROR; |
| | | } |
| | | |
| | | int CHsmsPassive::writeEquipmentConstantsToFile(const std::string& filepath) |
| | | { |
| | | if (filepath.empty()) return -1; |
| | | CFile file; |
| | | if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | const std::string headerAnsi = "ECID,EC Name,EC Format,EC Remark,Default Value\r\n"; |
| | | if (m_bEquipmentConstantUtf8) { |
| | | if (m_bEquipmentConstantUtf8Bom) { |
| | | const BYTE bom[3] = { 0xEF, 0xBB, 0xBF }; |
| | | file.Write(bom, 3); |
| | | } |
| | | CStringA header = AnsiToUtf8(headerAnsi); |
| | | file.Write(header.GetString(), header.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(headerAnsi.data(), (UINT)headerAnsi.size()); |
| | | } |
| | | for (const auto& e : m_equipmentConstants) { |
| | | std::string line; |
| | | line.reserve(128); |
| | | line += std::to_string(e.id); |
| | | line.push_back(','); |
| | | line += e.name; |
| | | line.push_back(','); |
| | | line += e.format; |
| | | line.push_back(','); |
| | | line += e.remark; |
| | | line.push_back(','); |
| | | line += e.value; |
| | | line.append("\r\n"); |
| | | if (m_bEquipmentConstantUtf8) { |
| | | CStringA out = AnsiToUtf8(line); |
| | | file.Write(out.GetString(), out.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(line.data(), (UINT)line.size()); |
| | | } |
| | | } |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | // S1F21/S1F22 - Data Variable Namelist |
| | | int CHsmsPassive::replyDataVariableNamelistRequest(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | std::vector<unsigned short> reqIds; |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | if (pBody != nullptr && pBody->getType() == SITYPE::L) { |
| | | const int sz = pBody->getSubItemSize(); |
| | | for (int i = 0; i < sz; ++i) { |
| | | unsigned short id = 0; |
| | | if (pBody->getSubItemU2(i, id)) { |
| | | reqIds.push_back(id); |
| | | } |
| | | } |
| | | } |
| | | |
| | | std::vector<unsigned short> dvids; |
| | | std::set<unsigned short> requested(reqIds.begin(), reqIds.end()); |
| | | Lock(); |
| | | if (reqIds.empty()) { |
| | | for (auto v : m_dataVariabels) { |
| | | if (v) dvids.push_back(static_cast<unsigned short>(v->getVarialbleId())); |
| | | } |
| | | } |
| | | else { |
| | | for (auto id : requested) dvids.push_back(id); |
| | | } |
| | | Unlock(); |
| | | |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 22, pRecv->getHeader()->systemBytes); |
| | | ASSERT(pMessage); |
| | | |
| | | ISECS2Item* pList = pMessage->getBody(); // L[n] of {DVID, DVNAME, UNITS} |
| | | for (auto id : dvids) { |
| | | ISECS2Item* pEntry = pList->addItem(); |
| | | pEntry->addU2Item(id, "DVID"); |
| | | SERVO::CDataVariable* v = getDataVariable((int)id); |
| | | if (v != nullptr) { |
| | | pEntry->addItem(v->getName().c_str(), "DVNAME"); |
| | | pEntry->addItem(v->getRemark().c_str(), "UNITS"); |
| | | } |
| | | else { |
| | | pEntry->addItem("", "DVNAME"); |
| | | pEntry->addItem("", "UNITS"); |
| | | } |
| | | } |
| | | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return ER_NOERROR; |
| | | } |
| | | |
| | | // S1F23 |
| | | int CHsmsPassive::replyCollectionEventNamelistRequest(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | std::vector<unsigned short> reqIds; |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | if (pBody != nullptr && pBody->getType() == SITYPE::L) { |
| | | const int sz = pBody->getSubItemSize(); |
| | | for (int i = 0; i < sz; ++i) { |
| | | unsigned short id = 0; |
| | | if (pBody->getSubItemU2(i, id)) { |
| | | reqIds.push_back(id); |
| | | } |
| | | } |
| | | } |
| | | |
| | | struct CEInfo { |
| | | unsigned short id{ 0 }; |
| | | std::string name; |
| | | std::vector<unsigned short> vids; |
| | | }; |
| | | std::vector<CEInfo> ceInfos; |
| | | { |
| | | Lock(); |
| | | if (reqIds.empty()) { |
| | | for (auto e : m_collectionEvents) { |
| | | if (e == nullptr) continue; |
| | | CEInfo info; |
| | | info.id = static_cast<unsigned short>(e->getEventId()); |
| | | info.name = e->getName(); |
| | | std::set<unsigned short> vidSet; |
| | | for (auto rpt : e->getReports()) { |
| | | if (rpt == nullptr) continue; |
| | | for (auto vid : rpt->getVids()) { |
| | | vidSet.insert(static_cast<unsigned short>(vid)); |
| | | } |
| | | } |
| | | info.vids.assign(vidSet.begin(), vidSet.end()); |
| | | ceInfos.push_back(std::move(info)); |
| | | } |
| | | } |
| | | else { |
| | | for (auto id : reqIds) { |
| | | CEInfo info; |
| | | info.id = id; |
| | | SERVO::CCollectionEvent* e = getEvent(id); |
| | | if (e != nullptr) { |
| | | info.name = e->getName(); |
| | | std::set<unsigned short> vidSet; |
| | | for (auto rpt : e->getReports()) { |
| | | if (rpt == nullptr) continue; |
| | | for (auto vid : rpt->getVids()) { |
| | | vidSet.insert(static_cast<unsigned short>(vid)); |
| | | } |
| | | } |
| | | info.vids.assign(vidSet.begin(), vidSet.end()); |
| | | } |
| | | ceInfos.push_back(std::move(info)); |
| | | } |
| | | } |
| | | Unlock(); |
| | | } |
| | | |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 24, pRecv->getHeader()->systemBytes); |
| | | ASSERT(pMessage); |
| | | |
| | | ISECS2Item* pList = pMessage->getBody(); // Body is L[n] of {CEID, CENAME, L[VIDs]} |
| | | for (const auto& info : ceInfos) { |
| | | ISECS2Item* pEntry = pList->addItem(); |
| | | pEntry->addU2Item(info.id, "CEID"); |
| | | pEntry->addItem(info.name.c_str(), "CENAME"); // empty if unknown |
| | | ISECS2Item* pVidList = pEntry->addItem(); |
| | | for (auto vid : info.vids) { |
| | | pVidList->addU2Item(vid, "VID"); |
| | | } |
| | | } |
| | | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return ER_NOERROR; |
| | | } |
| | | |
| | | // S2F13 |
| | |
| | | } |
| | | |
| | | |
| | | // è¦è·åç常é表表 |
| | | BOOL bCheckData = FALSE; |
| | | std::vector<EQConstant> eqcs; |
| | | { |
| | | ISECS2Item* pItem = pRecv->getBody(); |
| | | int ecidSize = pItem->getSubItemSize(); |
| | | const int ecidSize = pItem ? pItem->getSubItemSize() : 0; |
| | | for (int i = 0; i < ecidSize; i++) { |
| | | EQConstant eqc; |
| | | unsigned short id; |
| | | if (pItem->getSubItemU2(i, id)) { |
| | | EQConstant eqc{}; |
| | | unsigned short id = 0; |
| | | if (pItem && pItem->getSubItemU2(i, id)) { |
| | | eqc.id = id; |
| | | eqcs.push_back(eqc); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 交ç±ä¸å±åºç¨æ¥è·åæºå¨å¸¸éå¼ |
| | | if (m_listener.onEQConstantRequest != nullptr) { |
| | | m_listener.onEQConstantRequest(this, eqcs); |
| | | // 空å表表示请æ±å
¨é¨ ECID |
| | | if (eqcs.empty()) { |
| | | for (const auto& e : m_equipmentConstants) { |
| | | EQConstant eqc{}; |
| | | eqc.id = e.id; |
| | | strcpy_s(eqc.szValue, EQCONSTANT_VALUE_MAX, e.value.c_str()); |
| | | eqcs.push_back(eqc); |
| | | } |
| | | |
| | | } else { |
| | | for (auto& item : eqcs) { |
| | | auto it = std::find_if(m_equipmentConstants.begin(), m_equipmentConstants.end(), |
| | | [&](const EquipmentConstantEntry& e) { return e.id == item.id; }); |
| | | if (it != m_equipmentConstants.end()) { |
| | | strcpy_s(item.szValue, EQCONSTANT_VALUE_MAX, it->value.c_str()); |
| | | } else { |
| | | item.szValue[0] = '\0'; // unknown -> empty |
| | | } |
| | | } |
| | | } |
| | | |
| | | // åå¤ |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 14, pRecv->getHeader()->systemBytes); |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 2, 14, pRecv->getHeader()->systemBytes); |
| | | ASSERT(pMessage); |
| | | ISECS2Item* pItem = pMessage->getBody(); |
| | | for (auto& item : eqcs) { |
| | |
| | | } |
| | | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SECS Msg SEND]S2F14 (SysByte=%u)", pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | |
| | | } |
| | | |
| | | |
| | | // è¦è®¾ç½®ç常é表表 |
| | | BOOL bCheckData = FALSE; |
| | | // è¦è®¾ç½®ç常é表 |
| | | std::vector<EQConstant> eqcs; |
| | | { |
| | | ISECS2Item* pItem = pRecv->getBody(); |
| | | int ecidSize = pItem->getSubItemSize(); |
| | | int ecidSize = pItem ? pItem->getSubItemSize() : 0; |
| | | for (int i = 0; i < ecidSize; i++) { |
| | | ISECS2Item* pItemEqc = pItem->getSubItem(i); |
| | | if (pItemEqc != nullptr) { |
| | | EQConstant eqc; |
| | | unsigned short eqcid; |
| | | const char* pszValue; |
| | | ISECS2Item* pItemEqc = pItem ? pItem->getSubItem(i) : nullptr; |
| | | if (pItemEqc == nullptr) continue; |
| | | EQConstant eqc{}; |
| | | unsigned short eqcid = 0; |
| | | const char* pszValue = nullptr; |
| | | if (pItemEqc->getSubItemU2(0, eqcid) |
| | | && pItemEqc->getSubItemString(1, pszValue)) { |
| | | eqc.id = eqcid; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | // æ´æ°å
å表并è½ç |
| | | bool changed = false; |
| | | for (auto& item : eqcs) { |
| | | auto it = std::find_if(m_equipmentConstants.begin(), m_equipmentConstants.end(), |
| | | [&](const EquipmentConstantEntry& e) { return e.id == item.id; }); |
| | | if (it != m_equipmentConstants.end()) { |
| | | it->value = item.szValue; |
| | | changed = true; |
| | | } |
| | | |
| | | |
| | | // 交ç±ä¸å±åºç¨æ¥ä¿åå设置æºå¨å¸¸éå¼ |
| | | std::vector<unsigned int> ecvs; |
| | | if (m_listener.onEQConstantSend != nullptr) { |
| | | m_listener.onEQConstantSend(this, eqcs); |
| | | } |
| | | if (changed && !m_strEquipmentConstantFilepath.empty()) { |
| | | writeEquipmentConstantsToFile(m_strEquipmentConstantFilepath); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | ISECS2Item* defineItem, *rptListItem, * vidListItem; |
| | | unsigned int dataId, rptid, vid; |
| | | unsigned short dataId; |
| | | unsigned int rptid, vid; |
| | | |
| | | if (!pBody->getSubItemU4(0, dataId)) goto MYREPLY; |
| | | if (!pBody->getSubItemU2(0, dataId)) goto MYREPLY; |
| | | rptListItem = pBody->getSubItem(1); |
| | | if (rptListItem == nullptr) goto MYREPLY; |
| | | if (rptListItem->getSubItemSize() == 0) { |
| | | clearAllReport(); |
| | | clearAllReport(TRUE); |
| | | goto MYREPLY; |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | if (vids.empty()) { |
| | | deleteReport(rptid); |
| | | } else { |
| | | removeReport(rptid); |
| | | if (!vids.empty()) { |
| | | pReport = defineReport(rptid, vids); |
| | | } |
| | | |
| | |
| | | |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | ISECS2Item* linkItem, *ceidListItem, *rptListItem; |
| | | unsigned int dataId, ceid, rptid; |
| | | if (!pBody->getSubItemU4(0, dataId)) goto MYREPLY; |
| | | unsigned short dataId; |
| | | unsigned int ceid, rptid; |
| | | bool bChanged = false; |
| | | if (!pBody->getSubItemU2(0, dataId)) goto MYREPLY; |
| | | ceidListItem = pBody->getSubItem(1); |
| | | if (ceidListItem == nullptr) goto MYREPLY; |
| | | for (int i = 0; i < ceidListItem->getSubItemSize(); i++) { |
| | |
| | | int prtCount = rptListItem->getSubItemSize(); |
| | | if (prtCount == 0) { |
| | | unlinkEventReport(ceid); |
| | | bChanged = true; |
| | | } |
| | | else { |
| | | for (int k = 0; k < prtCount; k++) { |
| | | if (rptListItem->getSubItemU4(k, rptid)) { |
| | | linkEventReport(ceid, rptid); |
| | | bChanged = true; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // æä¹
åå° CollectionEventList.txtï¼ä¾¿äºä¸æ¬¡å¯å¨ä»ä¿æ Link/Unlink ç»æï¼ |
| | | if (bChanged && !m_strCollectionEventFilepath.empty()) { |
| | | writeCollectionEventsToFile(m_strCollectionEventFilepath); |
| | | } |
| | | |
| | | // æ£éªç»ææ¯å¦æ£ç¡® |
| | | for (auto item : m_collectionEvents) { |
| | | LOGE("=== ceid:%d, prtid:%d", item->getEventId(), item->getFirstPortID()); |
| | | unsigned int reportId = item->getFirstReportID(); |
| | | if(reportId != 0) |
| | | LOGI("=== ceid:%d, prtid:%d", item->getEventId(), reportId); |
| | | else |
| | | LOGI("=== ceid:%d, prtid:--", item->getEventId()); |
| | | } |
| | | |
| | | MYREPLY: |
| | |
| | | |
| | | // æ¸
ç©ºææ |
| | | if (pBody->getSubItemSize() == 0) { |
| | | m_spoolingConfig.clear(); |
| | | LOGI("<CHsmsPassive>turns off all streams and fns"); |
| | | m_spoolBlacklistByStream.clear(); |
| | | m_spoolingEnabled = false; |
| | | goto MYREPLY; |
| | | } |
| | | m_spoolingEnabled = true; |
| | | |
| | | // 便¬¡é
ç½®Stream |
| | | for (int i = 0; i < pBody->getSubItemSize(); i++) { |
| | |
| | | unsigned char STRID, FCNID; |
| | | pStreamItem->getSubItemU1(0, STRID); |
| | | ISECS2Item* pFcnItemList = pStreamItem->getSubItem(1); |
| | | if (pFcnItemList->getSubItemSize() == 0) { |
| | | m_spoolingConfig[STRID].clear(); |
| | | if (pFcnItemList == nullptr || pFcnItemList->getSubItemSize() == 0) { |
| | | // No functions listed => blacklist the whole stream |
| | | m_spoolBlacklistByStream[STRID].clear(); |
| | | } |
| | | else { |
| | | // Update blacklist for this stream |
| | | m_spoolBlacklistByStream[STRID].clear(); |
| | | for (int j = 0; j < pFcnItemList->getSubItemSize(); j++) { |
| | | pFcnItemList->getSubItemU1(j, FCNID); |
| | | m_spoolingConfig[STRID].insert(FCNID); |
| | | m_spoolBlacklistByStream[STRID].insert(FCNID); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // æå°éªè¯ç»æ |
| | | for (auto s : m_spoolingConfig) { |
| | | LOGI("====> stream:%d", s.first); |
| | | for (auto s : m_spoolBlacklistByStream) { |
| | | LOGI("====> spool blacklist stream:%d", s.first); |
| | | if (s.second.empty()) { |
| | | LOGI("blacklist all functions"); |
| | | } |
| | | else { |
| | | for (auto f : s.second) { |
| | | LOGI("function:%d", f); |
| | | LOGI("blacklist function:%d", f); |
| | | } |
| | | } |
| | | } |
| | | MYREPLY: |
| | | replyAck(2, 42, pRecv->getHeader()->systemBytes, BYTE(0), "ERACK"); |
| | | replyAck(2, 44, pRecv->getHeader()->systemBytes, BYTE(0), "ERACK"); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | goto MYREPLY; |
| | | } |
| | | |
| | | if (!isHostCommandAllowed()) { |
| | | CAACK = CAACK_5; |
| | | ERRCODE = CAACK_5; |
| | | strError = "rejected - ControlState not OnlineRemote"; |
| | | goto MYREPLY; |
| | | } |
| | | |
| | | |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR; |
| | | |
| | | unsigned int DATAID; |
| | | unsigned short DATAID; |
| | | unsigned char PTN; |
| | | const char* pszCarrierAction, *pszCarrierId; |
| | | pBody->getSubItemU4(0, DATAID); |
| | | pBody->getSubItemU2(0, DATAID); |
| | | pBody->getSubItemString(1, pszCarrierAction); |
| | | pBody->getSubItemString(2, pszCarrierId); |
| | | pBody->getSubItemU1(3, PTN); |
| | |
| | | pErrItem->addU4Item(ERRCODE, "ERRCODE"); |
| | | pErrItem->addItem(strError.c_str(), "ERRTEXT"); |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SECS Msg SEND]S3F18 (SysByte=%u)", pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | |
| | | |
| | | // ä¸¢å¼ |
| | | if (RSDC == 1) { |
| | | LOGI("<CHsmsPassive>Purge Spooled Data."); |
| | | Lock(); |
| | | for (auto item : m_listActionSpooling) { |
| | | delete item; |
| | |
| | | Unlock(); |
| | | } |
| | | else { |
| | | LOGI("<CHsmsPassive>Request Spooled Data."); |
| | | Lock(); |
| | | for (auto item : m_listActionSpooling) { |
| | | m_listAction.push_back(item); |
| | |
| | | SetEvent(m_hCimWorkEvent); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | // S7F17 Delete Process Program (PPID list) / S7F18 |
| | | int CHsmsPassive::replyDeletePPID(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | |
| | | bool allOk = true; |
| | | const bool deleteAll = (pRecv->getBody() == nullptr || pRecv->getBody()->getSubItemSize() == 0); |
| | | std::vector<std::string> ppids; |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | const int nCount = pBody ? pBody->getSubItemSize() : 0; |
| | | for (int i = 0; i < nCount; ++i) { |
| | | const char* pszPPID = nullptr; |
| | | if (pBody->getSubItemString(i, pszPPID) && pszPPID != nullptr) { |
| | | ppids.emplace_back(pszPPID); |
| | | } |
| | | else { |
| | | allOk = false; |
| | | } |
| | | } |
| | | |
| | | if (deleteAll || !ppids.empty()) { |
| | | if (m_listener.onDeletePPID != nullptr) { |
| | | allOk = m_listener.onDeletePPID(this, ppids); |
| | | } |
| | | else { |
| | | // no handler provided; treat as failure |
| | | allOk = false; |
| | | LOGW("<HSMS>DeletePPID request ignored: no onDeletePPID listener"); |
| | | } |
| | | } |
| | | |
| | | |
| | | replyAck(7, 18, pRecv->getHeader()->systemBytes, allOk ? BYTE(0) : BYTE(1), "ACKC7"); |
| | | return 0; |
| | | } |
| | | |
| | | // S7F5 Process Program Request -> reply S7F6 with PPID + PPBODY |
| | | int CHsmsPassive::replyProcessProgramRequest(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | const char* pszPPID = nullptr; |
| | | if (pBody == nullptr || !pBody->getString(pszPPID) || pszPPID == nullptr) { |
| | | return ER_PARAM_ERROR; |
| | | } |
| | | std::string ppid(pszPPID); |
| | | std::string ppbody; |
| | | // ç®åèåï¼ä» RecipeManager å设å¤é
æ¹ï¼æ¼æææ¬ |
| | | auto recipeInfo = RecipeManager::getInstance().getRecipeByPPID(ppid); |
| | | if (!recipeInfo.strPPID.empty()) { |
| | | for (const auto& dev : recipeInfo.vecDeviceList) { |
| | | if (!ppbody.empty()) ppbody.append("\n"); |
| | | ppbody.append(dev.strDeviceName); |
| | | ppbody.append(","); |
| | | ppbody.append(std::to_string(dev.nRecipeID)); |
| | | ppbody.append(","); |
| | | ppbody.append(dev.strRecipeName); |
| | | // éå 忰大å°ä¿¡æ¯ï¼ç®å缺å°å
·ä½åæ°åè¡¨ï¼ |
| | | ppbody.append(",paramsSize="); |
| | | ppbody.append(std::to_string(dev.paramsRawData.size())); |
| | | } |
| | | } |
| | | |
| | | IMessage* pMessage = nullptr; |
| | | if (HSMS_Create1Message(pMessage, m_nSessionId, 7, 6, pRecv->getHeader()->systemBytes) != 0 || pMessage == nullptr) { |
| | | return ER_CREATED_MESSAGE; |
| | | } |
| | | ISECS2Item* pRspBody = pMessage->getBody(); // top-level L:2 |
| | | pRspBody->addItem(ppid.c_str(), "PPID"); |
| | | pRspBody->addItem(ppbody.c_str(), "PPBODY"); |
| | | m_pPassive->sendMessage(pMessage); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SECS Msg SEND]S7F20 (SysByte=%u)", pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | |
| | | ISECS2Item* pReplyItemAcks = pReply->getBody()->addItem(); |
| | | ISECS2Item* pReplyItemAck = pReplyItemAcks->addU1Item(0, "OBJACK"); |
| | | ISECS2Item* pReplyItemErrs = pReplyItemAcks->addItem(); |
| | | |
| | | if (!isHostCommandAllowed()) { |
| | | ISECS2Item* pItemError = pReplyItemErrs->addItem(); |
| | | pItemError->addU4Item(2001, "ERRCODE"); |
| | | pItemError->addItem("rejected - ControlState not OnlineRemote", "ERRTEXT"); |
| | | goto MYREPLY; |
| | | } |
| | | |
| | | // å½ååªå¤çç±»å为ControlJob |
| | | if (_strcmpi(pszObjType, "ControlJob") == 0) { |
| | |
| | | MYREPLY: |
| | | pReplyItemAck->setU1(bCreateOk ? 0 : 1, "OBJACK"); |
| | | m_pPassive->sendMessage(pReply); |
| | | LOGI("<HSMS>[SECS Msg SEND]S14F10 (SysByte=%u)", pReply->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pReply->getHeader()->sessionId, pReply->getHeader()->sType, pReply->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pReply); |
| | | HSMS_Destroy1Message(pReply); |
| | | |
| | | |
| | |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR; |
| | | |
| | | if (!isHostCommandAllowed()) { |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 16, 16, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | | ISECS2Item* pItemPrjobIds = pMessage->getBody()->addItem(); |
| | | ISECS2Item* pItemErrors = pMessage->getBody()->addItem(); |
| | | pItemErrors->addBoolItem(false, "ACKA"); |
| | | ISECS2Item* pItemErrors2 = pItemErrors->addItem(); |
| | | auto err = pItemErrors2->addItem(); |
| | | err->addU4Item(2001, "ERRCODE"); |
| | | err->addItem("rejected - ControlState not OnlineRemote", "ERRTEXT"); |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | // è§£éæ°æ®ï¼å¾å°CProcessJob |
| | | // 容éåç½®æ£æ¥ï¼å½åå®ç°ä»
æ¯æåæ¹ PJ éåï¼å¦æå·²æ PJ/CJï¼ç´æ¥è¿å ACKA=false |
| | | if (m_pModel != nullptr && !m_pModel->getMaster().isProcessJobsEmpty()) { |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 16, 16, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | | pMessage->getBody()->addItem(); // PRJOBID list 为空 |
| | | ISECS2Item* pItemErrors = pMessage->getBody()->addItem(); |
| | | pItemErrors->addBoolItem(false, "ACKA"); |
| | | ISECS2Item* pItemErrors2 = pItemErrors->addItem(); |
| | | auto err = pItemErrors2->addItem(); |
| | | err->addU4Item(1000, "ERRCODE"); |
| | | err->addItem("PJobSpace=0 (existing ProcessJob/ControlJob)", "ERRTEXT"); |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | return 0; |
| | | } |
| | | |
| | | ISECS2Item* pItemPjs, * pItemPj,* pItemCarriers, * pItemCarrier, *pItemSlots, *pItemRecipes; |
| | | unsigned int DATAID; |
| | | unsigned short DATAID; |
| | | const char* pszPrjobid, *pszMF, *pszCarrierId, *pszRecipeName; |
| | | std::string strCarrierId; |
| | | unsigned int len; |
| | |
| | | std::vector<unsigned char> slots; |
| | | std::vector<SERVO::CProcessJob*> pjs; |
| | | |
| | | if (!pBody->getSubItemU4(0, DATAID)) return ER_PARAM_ERROR; |
| | | if (!pBody->getSubItemU2(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++) { |
| | |
| | | pjs.push_back(pj); |
| | | } |
| | | |
| | | |
| | | ASSERT(m_listener.onPRJobMultiCreate != nullptr); |
| | | int nRet = m_listener.onPRJobMultiCreate(this, pjs); |
| | | |
| | | |
| | | // å夿¥æ |
| | | // å夿¥æï¼å¨æ ¡éª/è½åºåååå¤ï¼ä»¥ä¾¿å¸¦ä¸çå®ç issuesï¼ |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 16, 16, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | |
| | | } |
| | | } |
| | | } |
| | | else { |
| | | pItemErrors->addBoolItem(true, "ACKA"); |
| | | pItemErrors->addItem(); // 空å表 |
| | | } |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SECS Msg SEND]S16F16 (SysByte=%u)", pMessage->getHeader()->systemBytes); |
| | | LOGI("<HSMS>[SEND]sessionId:%d, sType:%d systemBytes:%d", |
| | | pMessage->getHeader()->sessionId, pMessage->getHeader()->sType, pMessage->getHeader()->systemBytes); |
| | | LogSecsMessageBrief("<HSMS>[SEND]", pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | |
| | |
| | | CHsmsAction* pAction = new CHsmsAction(ACTION_ALARM_REPORT, TRUE, m_nActionTimeout); |
| | | |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 5 | REPLY, 1, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | | if (HSMS_Create1Message(pMessage, m_nSessionId, 5 | REPLY, 1, ++m_nSystemByte) != 0 || pMessage == NULL) { |
| | | LOGE("<HSMS>S5F1 create message failed"); |
| | | delete pAction; |
| | | Unlock(); |
| | | return ER_CREATED_MESSAGE; |
| | | } |
| | | ISECS2Item* pItem = pMessage->getBody(); |
| | | pItem->addBinaryItem(szALCD, 1, "ALCD"); |
| | | pItem->addU4Item(ALID, "ALID"); |
| | | pItem->addItem(ALTX, "ALTX"); |
| | | pAction->setSendMessage(pMessage); |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | if (shouldSpool(5, 1)) { |
| | | m_listActionSpooling.push_back(pAction); |
| | | } |
| | | else { |
| | | LOGI("<HSMS>spooling disabled for S5F1, drop alarm report"); |
| | | delete pAction; |
| | | } |
| | | } |
| | | else { |
| | | m_listAction.push_back(pAction); |
| | |
| | | } |
| | | |
| | | // S6F11 |
| | | static unsigned int DATAID = 1; |
| | | static unsigned short DATAID = 0; |
| | | int CHsmsPassive::requestEventReportSend(unsigned int CEID) |
| | | { |
| | | SERVO::CCollectionEvent* pEvent = getEvent(CEID); |
| | | if (pEvent == nullptr) { |
| | | return ER_NO_EVENT; |
| | | } |
| | | // 触å PauseEvent æ£æµæ¡©ï¼ç± Master è´è´£å®é
çç¥ï¼ |
| | | if (m_pModel != nullptr) { |
| | | m_pModel->getMaster().handleCollectionEvent(CEID); |
| | | } |
| | | |
| | | SERVO::CReport* pReport = pEvent->getFirstReport(); |
| | | if (pReport == nullptr) { |
| | | return ER_UNLINK_EVENT_REPORT; |
| | | } |
| | | |
| | | |
| | | Lock(); |
| | | CHsmsAction* pAction = new CHsmsAction(ACTION_EVENT_REPORT, TRUE, m_nActionTimeout); |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 6 | REPLY, 11, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | | if (HSMS_Create1Message(pMessage, m_nSessionId, 6 | REPLY, 11, ++m_nSystemByte) != 0 || pMessage == NULL) { |
| | | LOGE("<HSMS>S6F11 create message failed"); |
| | | delete pAction; |
| | | Unlock(); |
| | | return ER_CREATED_MESSAGE; |
| | | } |
| | | ISECS2Item* pItem = pMessage->getBody(); |
| | | pItem->addU4Item(++DATAID, "DATAID"); |
| | | pItem->addU4Item(CEID, "CEID"); |
| | | ISECS2Item* pItemList1 = pItem->addItem(); |
| | | // pItem->addU2Item(++DATAID, "DATAID"); // æ ¹æ®å«çæ¥å¿æ¾ç¤ºDATAIDæä¸º0ï¼æä»¥æä»¬å
ç
§ä½¿ç¨0 |
| | | pItem->addU2Item(0, "DATAID"); |
| | | std::string ceidNote("CEID"); |
| | | if (pEvent != nullptr) { |
| | | auto& name = pEvent->getName(); |
| | | if (!name.empty()) { |
| | | ceidNote += " -> "; |
| | | ceidNote += name; |
| | | } |
| | | } |
| | | pItem->addU4Item(CEID, ceidNote.c_str()); |
| | | ISECS2Item* pItemList1 = pItem->addItem(); // L[n] reports |
| | | if (pReport != nullptr) { |
| | | ISECS2Item* pItemList2 = pItemList1->addItem(); |
| | | pItemList2->addU4Item(pReport->getReportId(), "RPTID"); |
| | | ISECS2Item* pItemList3 = pItemList2->addItem(); |
| | |
| | | for (auto var : vars) { |
| | | addVariableValueToItem(pItemList3, var); |
| | | } |
| | | } |
| | | pAction->setSendMessage(pMessage); |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | if (shouldSpool(6, 11)) { |
| | | m_listActionSpooling.push_back(pAction); |
| | | } |
| | | else { |
| | | LOGI("<HSMS>spooling disabled for S6F11, drop event report (CEID=%u)", CEID); |
| | | delete pAction; |
| | | } |
| | | } |
| | | else { |
| | | m_listAction.push_back(pAction); |
| | |
| | | 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("Panel_End"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_OCR_PanelID_Read_OK() |
| | | { |
| | | return requestEventReportSend_OCR_PanelID_Read(1); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_OCR_PanelID_Read(short vcrResult) |
| | | { |
| | | const char* eventName = "OCR_PanelID_Read_OK"; |
| | | switch (vcrResult) { |
| | | case 1: // OK & Match |
| | | eventName = "OCR_PanelID_Read_OK"; |
| | | break; |
| | | case 2: // OK & Mismatch |
| | | eventName = "OCR_PanelID_Read_Mismatch"; |
| | | break; |
| | | case 3: // Fail & KeyIn Match |
| | | eventName = "OCR_PanelID_Read_NG"; |
| | | break; |
| | | case 4: // Fail & KeyIn Mismatch |
| | | eventName = "OCR_PanelID_Read_NG_Mismatch"; |
| | | break; |
| | | default: |
| | | LOGE("<CHsmsPassive>Unknown VCR result=%d, fallback to OCR_PanelID_Read_OK", vcrResult); |
| | | eventName = "OCR_PanelID_Read_OK"; |
| | | break; |
| | | } |
| | | |
| | | return requestEventReportSend(eventName); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_LoadPortNotAssoc() |
| | | { |
| | | return requestEventReportSend("LoadPortNotAssoc"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_ProcessDataReport() |
| | | { |
| | | return requestEventReportSend("ProcessDataReport"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_SubEqpStart() |
| | | { |
| | | return requestEventReportSend("SubEqpStart"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_SubEqpEnd() |
| | | { |
| | | return requestEventReportSend("SubEqpEnd"); |
| | | } |
| | | |
| | | |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include <string> |
| | | #include <list> |
| | | #include "HsmsAction.h" |
| | |
| | | #include "CCollectionEvent.h" |
| | | #include "ProcessJob.h" |
| | | #include "CControlJob.h" |
| | | #include "CDataVariable.h" |
| | | |
| | | |
| | | #define EQCONSTANT_VALUE_MAX 64 |
| | |
| | | #define ER_UNLINK_EVENT_REPORT -5 |
| | | #define ER_NO_PPID_LIST -6 |
| | | #define ER_NOT_SUPPORTED -7 |
| | | #define ER_CREATED_MESSAGE -8 |
| | | |
| | | |
| | | |
| | | /* CAACK */ |
| | |
| | | #define CAACK_6 6 /* command performed with errors */ |
| | | |
| | | /* |
| | | * 叏鿰æ®ç»æ |
| | | * 叏鿰æ®ç»æ |
| | | */ |
| | | typedef struct _EQConstant |
| | | { |
| | |
| | | } EQConstant; |
| | | |
| | | /* |
| | | * Command æ°æ®ç»æ |
| | | * Command æ°æ®ç»æ |
| | | */ |
| | | typedef struct _CommandParameter |
| | | { |
| | |
| | | } CommandParameter; |
| | | |
| | | /* |
| | | * Report æ°æ®ç»æ |
| | | * Report æ°æ®ç»æ |
| | | */ |
| | | typedef struct _REPORT |
| | | { |
| | |
| | | } REPORT; |
| | | |
| | | /* |
| | | * Value æ°æ®ç»æ |
| | | * Value æ°æ®ç»æ |
| | | */ |
| | | typedef struct _VALUE |
| | | { |
| | |
| | | |
| | | |
| | | typedef std::function<void(void* pFrom)> SECSEQOFFLINE; |
| | | typedef std::function<void(void* pFrom, std::vector<EQConstant>&)> SECSEQCONSTANTREQUEST; |
| | | typedef std::function<void(void* pFrom, const char*, std::vector<CommandParameter>&)> SECSCommand; |
| | | typedef std::function<void(void* pFrom, SYSTEMTIME& time)> DATETIMESYNC; |
| | | typedef std::function<void(void* pFrom, bool bEnable, std::vector<unsigned int>& ids)> EDEVENTREPORT; |
| | |
| | | std::string& strErrorTxt)> CARRIERACTION; |
| | | typedef std::function<int(void* pFrom, std::vector<SERVO::CProcessJob*>& pjs)> PRJOBMULTICREATE; |
| | | typedef std::function<int(void* pFrom, SERVO::CControlJob& controlJob)> CONTROLJOBCREATE; |
| | | typedef std::function<bool(void* pFrom, const std::vector<std::string>& ppids)> DELETEPPID; |
| | | typedef struct _SECSListener |
| | | { |
| | | SECSEQOFFLINE onEQOffLine; |
| | | SECSEQOFFLINE onEQOnLine; |
| | | SECSEQCONSTANTREQUEST onEQConstantRequest; |
| | | SECSEQCONSTANTREQUEST onEQConstantSend; |
| | | SECSCommand onCommand; |
| | | DATETIMESYNC onDatetimeSync; |
| | | EDEVENTREPORT onEnableDisableEventReport; |
| | | EDALARMREPORT onEnableDisableAlarmReport; |
| | | QUERYPPIDLIST onQueryPPIDList; |
| | | DELETEPPID onDeletePPID; |
| | | CARRIERACTION onCarrierAction; |
| | | PRJOBMULTICREATE onPRJobMultiCreate; |
| | | CONTROLJOBCREATE onControlJobCreate; |
| | |
| | | ~CHsmsPassive(); |
| | | |
| | | public: |
| | | /* 设置æºå¨åå· æå¤§é¿åº¦ 20 bytes */ |
| | | /* 设置æºå¨åå· æå¤§é¿åº¦ 20 bytes */ |
| | | void setEquipmentModelType(const char* pszMode); |
| | | |
| | | /* è®¾ç½®è½¯ä»¶çæ¬å· æå¤§é¿åº¦ 20 bytes */ |
| | | /* è®¾ç½®è½¯ä»¶çæ¬å· æå¤§é¿åº¦ 20 bytes */ |
| | | void setSoftRev(const char* pszRev); |
| | | |
| | | /* æ·»å åéå¼å°ISECS2Item */ |
| | | /* æ·»å åéå¼å°ISECS2Item */ |
| | | void addVariableValueToItem(ISECS2Item* pParent, SERVO::CVariable* pVariable); |
| | | |
| | | // è¿æ¥Report |
| | | // è¿æ¥Report |
| | | void linkEventReport(unsigned int CEID, unsigned int RPTID); |
| | | |
| | | // åæ¶è¿æ¥report |
| | | // åæ¶è¿æ¥report |
| | | void unlinkEventReport(unsigned int CEID); |
| | | |
| | | // define Report |
| | | SERVO::CReport* defineReport(unsigned int RPTID, std::vector<unsigned int>& vids); |
| | | |
| | | // åæ¶ define report |
| | | // åæ¶ define report |
| | | bool removeReport(int rptid); |
| | | void clearAllReport(); |
| | | int deleteReport(int rptid); |
| | | int addReport(int rptid, const std::vector<unsigned int>& vids); |
| | | int updateReport(int rptid, const std::vector<unsigned int>& vids); |
| | | void clearAllReport(BOOL bSave = FALSE); |
| | | |
| | | // 仿件ä¸å è½½CVariableå表 |
| | | // 仿件ä¸å è½½CVariableå表 |
| | | int loadVarialbles(const char* pszFilepath); |
| | | // 仿件ä¸å è½½CDataVariableå表 |
| | | int loadDataVarialbles(const char* pszFilepath); |
| | | // 仿件ä¸å è½½Equipment Constantå表 |
| | | int loadEquipmentConstants(const char* pszFilepath); |
| | | |
| | | // åå¾CVariableå表 |
| | | // åå¾CVariableå表 |
| | | std::vector<SERVO::CVariable*>& getVariables(); |
| | | unsigned int getMaxVariableId() const; |
| | | std::vector<SERVO::CDataVariable*>& getDataVariables(); |
| | | unsigned int getMaxDataVariableId() const; |
| | | |
| | | // å徿å®Variable |
| | | // å徿å®Variable |
| | | SERVO::CVariable* getVariable(int variableId); |
| | | SERVO::CVariable* getVariable(const char* pszName); |
| | | SERVO::CDataVariable* getDataVariable(int dvid); |
| | | SERVO::CDataVariable* getDataVariable(const char* pszName); |
| | | int getCurrentControlState(); |
| | | bool isHostCommandAllowed(); |
| | | int deleteVariable(int variableId); |
| | | int addVariable(const char* pszName, const char* pszFormat, const char* pszRemark, int& outId); |
| | | int updateVariable(int variableId, const char* pszName, const char* pszFormat, const char* pszRemark); |
| | | int deleteDataVariable(int dvid); |
| | | int addDataVariable(const char* pszName, const char* pszFormat, const char* pszRemark, int& outId); |
| | | int updateDataVariable(int dvid, const char* pszName, const char* pszFormat, const char* pszRemark); |
| | | |
| | | // 设置åéå¼ |
| | | // 设置åéå¼ |
| | | void setVariableValue(const char* pszName, __int64 value); |
| | | void setVariableValue(const char* pszName, const char* value); |
| | | void setVariableValue(const char* pszName, std::vector<SERVO::CVariable>& vars); |
| | | // æ§è¡ä¸æ®µæéç代ç åï¼ç¨äºä¿è¯ set+send çååæ§ |
| | | void withVariableLock(const std::function<void()>& fn); |
| | | |
| | | // 仿件ä¸å è½½CReportå表 |
| | | // 仿件ä¸å è½½CReportå表 |
| | | int loadReports(const char* pszFilepath); |
| | | |
| | | // åå¾Reportå表 |
| | | // åå¾Reportå表 |
| | | std::vector<SERVO::CReport*>& getReports(); |
| | | unsigned int getMaxReportId() const; |
| | | |
| | | // 仿件ä¸å è½½CCollectionEventå表 |
| | | // 仿件ä¸å è½½CCollectionEventå表 |
| | | int loadCollectionEvents(const char* pszFilepath); |
| | | |
| | | // åå¾CCollectionEventå表 |
| | | // åå¾CCollectionEventå表 |
| | | std::vector<SERVO::CCollectionEvent*>& getCollectionEvents(); |
| | | unsigned int getMaxCollectionEventId() const; |
| | | |
| | | // åæ¶/å 餿æCollectionEvent |
| | | // åæ¶/å 餿æCollectionEvent |
| | | void clearAllCollectionEvent(); |
| | | int deleteCollectionEvent(unsigned short CEID); |
| | | int addCollectionEvent(unsigned int CEID, const char* name, const char* desc, const std::vector<unsigned int>& rptids); |
| | | int updateCollectionEvent(unsigned int CEID, const char* name, const char* desc, const std::vector<unsigned int>& rptids); |
| | | |
| | | // åå¾CCollectionEvent |
| | | // åå¾CCollectionEvent |
| | | SERVO::CCollectionEvent* getEvent(unsigned short CEID); |
| | | |
| | | // åå¾Report |
| | | // åå¾Report |
| | | SERVO::CReport* getReport(int rptid); |
| | | |
| | | void setListener(SECSListener listener); |
| | |
| | | int unserialize(const char* pszBuffer, int nBufferSize); |
| | | |
| | | public: |
| | | /* requestå¼å¤´ç彿°ä¸ºä¸»å¨åéæ°æ®ç彿° */ |
| | | /* requestå¼å¤´ç彿°ä¸ºä¸»å¨åéæ°æ®ç彿° */ |
| | | int requestAreYouThere(); |
| | | int requestAlarmReport(int ALCD, int ALID, const char* ALTX); |
| | | 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(); |
| | |
| | | int requestEventReportSend_CJ_End(); |
| | | int requestEventReportSend_Panel_Start(); |
| | | int requestEventReportSend_Panel_End(); |
| | | int requestEventReportSend_OCR_PanelID_Read_OK(); |
| | | int requestEventReportSend_OCR_PanelID_Read(short vcrResult); |
| | | int requestEventReportSend_LoadPortNotAssoc(); |
| | | int requestEventReportSend_ProcessDataReport(); |
| | | int requestEventReportSend_SubEqpStart(); |
| | | int requestEventReportSend_SubEqpEnd(); |
| | | |
| | | private: |
| | | void replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName); |
| | | |
| | | /* replyå¼å¤´ç彿°ä¸ºåå¤å½æ° */ |
| | | /* replyå¼å¤´ç彿°ä¸ºåå¤å½æ° */ |
| | | int replyAreYouThere(IMessage* pRecv); |
| | | int replyEstablishCommunications(IMessage* pRecv); |
| | | int replySelectedEquipmentStatusData(IMessage* pRecv); |
| | | int replyStatusVariableNamelistRequest(IMessage* pRecv); // S1F11/S1F12 |
| | | int replyDataVariableNamelistRequest(IMessage* pRecv); // S1F21/S1F22 |
| | | int replyCollectionEventNamelistRequest(IMessage* pRecv); // S1F23/S1F24 |
| | | int replyOnLine(IMessage* pRecv); |
| | | int replyOffLine(IMessage* pRecv); |
| | | int replyEquipmentConstantRequest(IMessage* pRecv); |
| | |
| | | int replyEanbleDisableAlarmReport(IMessage* pRecv); |
| | | int replyPurgeSpooledData(IMessage* pRecv); |
| | | int replyQueryPPIDList(IMessage* pRecv); |
| | | int replyDeletePPID(IMessage* pRecv); // S7F17/S7F18 |
| | | int replyProcessProgramRequest(IMessage* pRecv); // S7F5/S7F6 |
| | | int replyTerminalDisplay(IMessage* pRecv); |
| | | int replyCreateObj(IMessage* pRecv); |
| | | int replyPRJobMultiCreate(IMessage* pRecv); |
| | |
| | | inline void Unlock() { LeaveCriticalSection(&m_criticalSection); } |
| | | int onRecvMsg(IMessage* pMessage); |
| | | void clearAllVariabel(); |
| | | void clearAllDataVariabel(); |
| | | std::vector<unsigned int> parseVidList(CString& strNums); |
| | | int writeVariablesToFile(const std::string& filepath); |
| | | int writeDataVariablesToFile(const std::string& filepath); |
| | | int writeEquipmentConstantsToFile(const std::string& filepath); |
| | | int writeReportsToFile(const std::string& filepath); |
| | | int writeCollectionEventsToFile(const std::string& filepath); |
| | | |
| | | private: |
| | | CModel* m_pModel; |
| | |
| | | |
| | | private: |
| | | SECSListener m_listener; |
| | | std::string m_strVariableFilepath; |
| | | bool m_bVariableUtf8{ false }; |
| | | bool m_bVariableUtf8Bom{ false }; |
| | | std::string m_strDataVariableFilepath; |
| | | bool m_bDataVariableUtf8{ false }; |
| | | bool m_bDataVariableUtf8Bom{ false }; |
| | | std::string m_strReportFilepath; |
| | | bool m_bReportUtf8{ false }; |
| | | bool m_bReportUtf8Bom{ false }; |
| | | std::string m_strCollectionEventFilepath; |
| | | bool m_bCollectionUtf8{ false }; |
| | | bool m_bCollectionUtf8Bom{ false }; |
| | | std::string m_strEquipmentConstantFilepath; |
| | | bool m_bEquipmentConstantUtf8{ false }; |
| | | bool m_bEquipmentConstantUtf8Bom{ false }; |
| | | BOOL m_bCimWorking; |
| | | HANDLE m_hCimWorkEvent; |
| | | HANDLE m_hCimWorkThreadHandle; |
| | |
| | | private: |
| | | // CVariable vector |
| | | std::vector<SERVO::CVariable*> m_variabels; |
| | | // CDataVariable vector |
| | | std::vector<SERVO::CDataVariable*> m_dataVariabels; |
| | | // Equipment constants |
| | | struct EquipmentConstantEntry { |
| | | unsigned int id{ 0 }; |
| | | std::string name; |
| | | std::string format; |
| | | std::string remark; |
| | | std::string value; |
| | | }; |
| | | std::vector<EquipmentConstantEntry> m_equipmentConstants; |
| | | |
| | | // CReport vector |
| | | std::vector<SERVO::CReport*> m_reports; |
| | |
| | | // CollectionEvent vector |
| | | std::vector<SERVO::CCollectionEvent*> m_collectionEvents; |
| | | |
| | | // Spooling Config |
| | | std::map<uint16_t, std::set<uint16_t>> m_spoolingConfig; |
| | | }; |
| | | // Spooling blacklist: StreamId -> {FunctionId...} |
| | | // In this map means DO NOT spool/cache. |
| | | // Special case: stream 1 is not spooled regardless of config. |
| | | // If a stream key exists with empty set => blacklist ALL functions in that stream. |
| | | std::map<uint16_t, std::set<uint16_t>> m_spoolBlacklistByStream; |
| | | bool m_spoolingEnabled{ true }; |
| | | |
| | | private: |
| | | bool shouldSpool(uint8_t streamId, uint8_t functionId) const; |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // LoginDlg.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "afxdialogex.h" |
| | | #include "LoginDlg2.h" |
| | | |
| | | |
| | | // CLoginDlg å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CLoginDlg2, CDialogEx) |
| | | |
| | | CLoginDlg2::CLoginDlg2(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_LOGIN, pParent) |
| | | { |
| | | } |
| | | |
| | | CLoginDlg2::~CLoginDlg2() |
| | | { |
| | | } |
| | | |
| | | void CLoginDlg2::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CLoginDlg2, CDialogEx) |
| | | ON_BN_CLICKED(IDC_BUTTON_LOGIN, &CLoginDlg2::OnBnClickedLogin) |
| | | ON_STN_CLICKED(IDC_STATIC_CHANGE_PASSWORD, &CLoginDlg2::OnBnClickedChangePassword) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CLoginDlg æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | BOOL CLoginDlg2::OnInitDialog() |
| | | { |
| | | CDialog::OnInitDialog(); |
| | | |
| | | // 设置çªå£æ é¢ååå§å¼ |
| | | SetWindowText(_T("ç»å½")); |
| | | |
| | | |
| | | CStatic* pStaticImage = (CStatic*)GetDlgItem(IDC_STATIC_IMAGE); |
| | | ASSERT(pStaticImage); |
| | | |
| | | CString strIconPath; |
| | | strIconPath.Format(_T("%s\\Res\\Operator_High_32.ico"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | HICON hIcon = (HICON)::LoadImage( |
| | | nullptr, |
| | | strIconPath, |
| | | IMAGE_ICON, |
| | | 32, // 徿 宽度 |
| | | 32, // 徿 é«åº¦ |
| | | LR_LOADFROMFILE); |
| | | if (hIcon) { |
| | | // 设置 CStatic æ§ä»¶ä¸ºå¾æ æ ·å¼ |
| | | pStaticImage->ModifyStyle(0xF, SS_ICON); |
| | | pStaticImage->SetIcon(hIcon); |
| | | } |
| | | |
| | | // æ·»å SS_NOTIFYæ ·å¼ |
| | | CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_CHANGE_PASSWORD); |
| | | if (pStatic != nullptr) { |
| | | pStatic->ModifyStyle(0, SS_NOTIFY); |
| | | } |
| | | |
| | | GetDlgItem(IDC_CHECK_REMEMBER_PASSWORD)->ShowWindow(SW_HIDE); |
| | | |
| | | |
| | | // test |
| | | SetDlgItemText(IDC_EDIT_USERNAME, _T("admin")); |
| | | SetDlgItemText(IDC_EDIT_PASSWORD, _T("admin123")); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CLoginDlg2::OnBnClickedLogin() |
| | | { |
| | | GetDlgItemText(IDC_EDIT_USERNAME, m_strUsername); |
| | | GetDlgItemText(IDC_EDIT_PASSWORD, m_strPassword); |
| | | |
| | | if (m_strUsername.IsEmpty()) { |
| | | AfxMessageBox(_T("请è¾å
¥ç¨æ·å")); |
| | | GetDlgItem(IDC_EDIT_USERNAME)->SetFocus(); |
| | | return; |
| | | } |
| | | if (m_strPassword.IsEmpty()) { |
| | | AfxMessageBox(_T("请è¾å
¥å¯ç ")); |
| | | GetDlgItem(IDC_EDIT_PASSWORD)->SetFocus(); |
| | | return; |
| | | } |
| | | |
| | | |
| | | EndDialog(IDOK); |
| | | } |
| | | |
| | | void CLoginDlg2::OnBnClickedChangePassword() |
| | | { |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | |
| | | |
| | | // CLoginDlg å¯¹è¯æ¡ |
| | | |
| | | class CLoginDlg2 : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CLoginDlg2) |
| | | |
| | | public: |
| | | CLoginDlg2(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CLoginDlg2(); |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_LOGIN }; |
| | | #endif |
| | | |
| | | public: |
| | | CString m_strUsername; |
| | | CString m_strPassword; |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnBnClickedLogin(); |
| | | afx_msg void OnBnClickedChangePassword(); |
| | | DECLARE_MESSAGE_MAP() |
| | | }; |
| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "Model.h" |
| | | #include "Log.h" |
| | | #include "Common.h" |
| | |
| | | #include "TransferManager.h" |
| | | #include "RecipeManager.h" |
| | | #include "GlassLogDb.h" |
| | | #include "CParam.h" |
| | | #include "CJobDataS.h" |
| | | #include <algorithm> |
| | | #include <iomanip> |
| | | #include <sstream> |
| | | #include <array> |
| | | #include <map> |
| | | |
| | | |
| | | CModel::CModel() |
| | |
| | | { |
| | | } |
| | | |
| | | void CModel::refreshDerivedSVs() |
| | | { |
| | | // CJobSpace: how many ControlJobs can be created (current implementation supports 0/1). |
| | | m_hsmsPassive.setVariableValue("CJobSpace", (__int64)(m_master.canCreateControlJob() ? 1 : 0)); |
| | | |
| | | // PJobSpace: how many ProcessJobs can be created (current implementation supports 0/1). |
| | | m_hsmsPassive.setVariableValue("PJobSpace", (__int64)(m_master.isProcessJobsEmpty() ? 1 : 0)); |
| | | } |
| | | |
| | | void CModel::notifyControlJobChanged() |
| | | { |
| | | // 1) å·æ°æ´¾ç SV |
| | | refreshDerivedSVs(); |
| | | // 2) éç¥ä¸å± UIï¼RX_CODE_CONTROLJOB_CHANGEDï¼ |
| | | notify(RX_CODE_CONTROLJOB_CHANGED); |
| | | } |
| | | |
| | | bool CModel::raiseSoftAlarm(int alarmId, |
| | | const std::string& desc, |
| | | int level /*= -1*/, |
| | | int deviceId /*= 0*/, |
| | | int unitId /*= 0*/, |
| | | const char* deviceName /*= "Software"*/, |
| | | const char* unitName /*= "App"*/) |
| | | { |
| | | AlarmManager& alarmManager = AlarmManager::getInstance(); |
| | | const AlarmInfo* info = alarmManager.getAlarmInfoByID(alarmId); |
| | | |
| | | int severity = level; |
| | | if (severity < 0 && info != nullptr) severity = info->nAlarmLevel; |
| | | if (severity < 0) severity = 0; |
| | | |
| | | std::string descText = desc; |
| | | if (descText.empty() && info != nullptr) { |
| | | descText = !info->strDescription.empty() ? info->strDescription : info->strAlarmText; |
| | | } |
| | | if (descText.empty()) { |
| | | descText = CToolUnits::formatString("Alarm %d", alarmId); |
| | | } |
| | | |
| | | AlarmData alarmData; |
| | | alarmData.nId = alarmId; |
| | | alarmData.nSeverityLevel = severity; |
| | | alarmData.nDeviceId = deviceId; |
| | | alarmData.nUnitId = unitId; |
| | | alarmData.strDeviceName = deviceName; |
| | | alarmData.strUnitName = unitName; |
| | | // è¥æªæ¾å¼æä¾è®¾å¤/åå
åç§°ï¼å°è¯éè¿ deviceId/unitId è§£æï¼soft alarm é»è®¤å为 0ï¼ |
| | | if (alarmData.strDeviceName.empty()) { |
| | | alarmData.strDeviceName = alarmManager.getDeviceNameById(deviceId); |
| | | } |
| | | if (alarmData.strUnitName.empty()) { |
| | | alarmData.strUnitName = alarmManager.getUnitNameById(deviceId, unitId); |
| | | } |
| | | alarmData.strStartTime = CToolUnits::timeToString2(CToolUnits::getTimestamp()); |
| | | alarmData.strEndTime = ""; |
| | | alarmData.strDescription = descText; |
| | | |
| | | int nAlarmEventId = 0; |
| | | bool result = alarmManager.addAlarm(alarmData, nAlarmEventId); |
| | | if (result) { |
| | | notify(RX_CODE_ALARM_SET); |
| | | if (m_master.isAlarmReportEnable()) { |
| | | m_hsmsPassive.requestAlarmReport(1, alarmId, descText.c_str()); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | void CModel::clearSoftAlarm(int alarmId, int deviceId, int unitId) |
| | | { |
| | | AlarmManager& alarmManager = AlarmManager::getInstance(); |
| | | alarmManager.clearAlarmByAttributes(alarmId, deviceId, unitId, CToolUnits::getCurrentTimeString()); |
| | | notify(RX_CODE_ALARM_CLEAR); |
| | | if (m_master.isAlarmReportEnable()) { |
| | | const AlarmInfo* info = alarmManager.getAlarmInfoByID(alarmId); |
| | | std::string descText; |
| | | if (info != nullptr) descText = info->strAlarmText; |
| | | m_hsmsPassive.requestAlarmReport(0, alarmId, descText.c_str()); |
| | | } |
| | | } |
| | | |
| | | void CModel::setControlState(ControlState newState) |
| | | { |
| | | const auto prev = m_currentControlState; |
| | | if (newState != m_currentControlState) { |
| | | m_currentControlState = newState; |
| | | // S6F11 (CEID=600): ControlStateChanged |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PreviousControlState", (__int64)static_cast<uint8_t>(prev)); |
| | | m_hsmsPassive.setVariableValue("CurrentControlState", (__int64)static_cast<uint8_t>(m_currentControlState)); |
| | | m_hsmsPassive.requestEventReportSend("ControlStateChanged"); |
| | | }); |
| | | notifyInt(RX_CODE_CONTROL_STATE_CHANGED, static_cast<int>(m_currentControlState)); |
| | | } else { |
| | | // Keep SV in sync even if unchanged/load-time refresh. |
| | | m_hsmsPassive.setVariableValue("CurrentControlState", (__int64)static_cast<uint8_t>(m_currentControlState)); |
| | | } |
| | | } |
| | | |
| | | IObservable* CModel::getObservable() |
| | | { |
| | | if (m_pObservable == nullptr) { |
| | | m_pObservable = RX_AllocaObservable([&](IObservableEmitter* e) -> void { |
| | | m_pObservableEmitter = e; // ä¿ååå°å¨ |
| | | m_pObservableEmitter = e; // ä¿ååå°å¨ |
| | | }); |
| | | } |
| | | |
| | |
| | | |
| | | int CModel::init() |
| | | { |
| | | const ULONGLONG boot_model_begin = GetTickCount64(); |
| | | CString strIniFile; |
| | | CString strUnitId; |
| | | strIniFile.Format(_T("%s\\ServoConfiguration.ini"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | m_configuration.setFilepath((LPTSTR)(LPCTSTR)strIniFile); |
| | | m_configuration.getUnitId(strUnitId); |
| | | |
| | | // æºå¨åå·åè½¯ä»¶çæ¬å·åºä»é
ç½®ä¸è¯»åï¼å½åå
åºå®å¼ |
| | | // æºå¨åå·åè½¯ä»¶çæ¬å·åºä»é
ç½®ä¸è¯»åï¼å½åå
åºå®å¼ |
| | | CString strModeType = _T("Master"); |
| | | CString strSoftRev = _T("1.0.2"); |
| | | |
| | | |
| | | // CGlassPool |
| | | m_glassPool.initPool(); |
| | | |
| | | // å° Model ä¸ä¸æä¼ éç» Masterï¼ä¾¿äº Master 触å软件级æ¥è¦çè·¨å±æä½ |
| | | m_master.setModelCtx(this); |
| | | |
| | | |
| | | // Log |
| | |
| | | CLog::GetLog()->SetLogsDir(strLogDir); |
| | | CLog::GetLog()->SetEquipmentId((LPTSTR)(LPCTSTR)strUnitId); |
| | | LOGI("\r\n\r\n~~~ Prog Start! ~~~"); |
| | | LOGI("[BOOT][MODEL] init begin"); |
| | | |
| | | |
| | | SECSListener listener; |
| | | listener.onEQOffLine = [&](void* pFrom) -> void { |
| | | LOGI("è¿ç¨è¯·æ±OffLine"); |
| | | listener.onEQOffLine = [this](void* pFrom) -> void { |
| | | LOGI("è¿ç¨è¯·æ±OffLine"); |
| | | (void)pFrom; |
| | | setControlState(ControlState::OfflineHost); |
| | | }; |
| | | listener.onEQOnLine = [&](void* pFrom) -> void { |
| | | LOGI("è¿ç¨è¯·æ±OnLine"); |
| | | listener.onEQOnLine = [this](void* pFrom) -> void { |
| | | LOGI("è¿ç¨è¯·æ±OnLine"); |
| | | (void)pFrom; |
| | | // Customer flow: S1F17 RequestOnline defaults to OnlineRemote. |
| | | setControlState(ControlState::OnlineRemote); |
| | | }; |
| | | listener.onCommand = [&](void* pFrom, const char* pszName, std::vector<CommandParameter>& params) -> void { |
| | | listener.onCommand = [this](void* pFrom, const char* pszName, std::vector<CommandParameter>& params) -> void { |
| | | LOGI("onCommand:%s", pszName); |
| | | (void)pFrom; |
| | | for (auto& item : params) { |
| | | LOGI("param:%s,%s", item.szName, item.szValue); |
| | | } |
| | | }; |
| | | listener.onEQConstantRequest = [&](void* pFrom, std::vector<EQConstant>& eqcs) -> void { |
| | | // 卿¤å¡«å
常éå¼ï¼ç®åä»
æ¯å 1åè¿å |
| | | for (auto& item : eqcs) { |
| | | sprintf_s(item.szValue, 256, "Test%d", item.id + 1); |
| | | |
| | | if (pszName == nullptr) return; |
| | | // S2F41 GoLocal / GoRemote (RCMD) |
| | | if (_strcmpi(pszName, "GoLocal") == 0 || _strcmpi(pszName, "LOCAL") == 0 || _strcmpi(pszName, "GoLOCAL") == 0) { |
| | | setControlState(ControlState::OnlineLocal); |
| | | } |
| | | }; |
| | | listener.onEQConstantSend = [&](void* pFrom, std::vector<EQConstant>& eqcs) -> void { |
| | | // 卿¤ä¿åå设置æºå¨å¸¸éå¼ |
| | | for (auto& item : eqcs) { |
| | | LOGI("onEQConstantRequest: %d, %s", item.id, item.szValue); |
| | | else if (_strcmpi(pszName, "GoRemote") == 0 || _strcmpi(pszName, "REMOTE") == 0 || _strcmpi(pszName, "GoREMOTE") == 0) { |
| | | setControlState(ControlState::OnlineRemote); |
| | | } |
| | | }; |
| | | listener.onDatetimeSync = [&](void* pFrom, SYSTEMTIME& time) -> void { |
| | |
| | | if (ids.empty()) { |
| | | m_master.enableEventReport(bEnable); |
| | | } |
| | | }; |
| | | listener.onDeletePPID = [&](void* pFrom, const std::vector<std::string>& ppids) -> bool { |
| | | (void)pFrom; |
| | | bool allOk = true; |
| | | std::vector<std::string> targets = ppids; |
| | | if (targets.empty()) { |
| | | // L:0 => delete all PPIDs |
| | | targets = RecipeManager::getInstance().getAllPPID(); |
| | | } |
| | | for (auto& ppid : targets) { |
| | | bool ok = RecipeManager::getInstance().deleteRecipeByPPID(ppid); |
| | | allOk = allOk && ok; |
| | | LOGI("<CModel>DeletePPID: %s, result=%s", ppid.c_str(), ok ? "OK" : "FAIL"); |
| | | } |
| | | return allOk; |
| | | }; |
| | | listener.onEnableDisableAlarmReport = [&](void* pFrom, bool bEnable, unsigned int id) -> void { |
| | | LOGI("onEnableDisableAlarmReport bEnable:%s, id:%d", bEnable ? _T("YES") : _T("NO"), id); |
| | |
| | | return CAACK_3; |
| | | } |
| | | |
| | | const unsigned int portIndex = PTN - 1; |
| | | SERVO::CLoadPort* pLoadPort = (SERVO::CLoadPort*)m_master.getEquipment(EQ_ID_LOADPORT1 + portIndex); |
| | | LOGI("<Model>onCarrierAction %d, %s, %d, %d", DATAID, pszCarrierAction, pszCarrierId, PTN); |
| | | |
| | | if (_strcmpi(pszCarrierAction, "ProceedWithCarrier") == 0) { |
| | | m_master.proceedWithCarrier(PTN); |
| | | // ææ¡£æµç¨ï¼ProceedWithCarrier ä¹å设å¤è¿å
¥ Check SlotMapï¼WFHï¼ï¼ |
| | | // çæ£çâå¼å§âç± ProceedWithSlotMap å³ç触åã |
| | | // ä»
彿ªå¼å¯ CompareMapsBeforeProceeding æ¶ï¼ææ²¿ç¨æ§é»è¾ç´æ¥ Startã |
| | | LOGI("<CModel>ProceedWithCarrier"); |
| | | if (m_master.getControlJob() == nullptr || m_master.isProcessJobsEmpty()) { |
| | | strErrorTxt = "rejected - ControlJob/ProcessJob not ready"; |
| | | LOGW("<CModel>ProceedWithCarrier rejected: no CJ/PJ, port=%d", portIndex + 1); |
| | | return CAACK_5; |
| | | } |
| | | 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 模å¼ï¼ä¸å
许æ¤å¨ä½ |
| | | LOGI("<CModel>ProceedWithSlotMap"); |
| | | if (pLoadPort == nullptr || !pLoadPort->isCompareMapsBeforeProceeding()) { |
| | | strErrorTxt = "rejected - SlotMap check disabled"; |
| | | return CAACK_5; |
| | | } |
| | | |
| | | const short scanMap = pLoadPort->getScanCassetteMap(); |
| | | const short downloadMap = pLoadPort->getDownloadCassetteMap(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("SlotMapScan", scanMap); |
| | | m_hsmsPassive.setVariableValue("SlotMapDownload", downloadMap); |
| | | if (scanMap != downloadMap) { |
| | | m_hsmsPassive.requestEventReportSend_SlotMapVerificationNG(); |
| | | m_hsmsPassive.requestEventReportSend("SlotMapMismatch"); |
| | | } |
| | | else { |
| | | m_hsmsPassive.requestEventReportSend_SlotMapVerificationOK(); |
| | | } |
| | | }); |
| | | |
| | | if (scanMap != downloadMap) { |
| | | strErrorTxt = "rejected - SlotMap mismatch"; |
| | | return CAACK_5; |
| | | } |
| | | |
| | | // Host 确认 SlotMap ååå¼å§å å·¥/æµç¨ |
| | | m_master.proceedWithCarrier(portIndex); |
| | | return CAACK_0; |
| | | } |
| | | else if (_strcmpi(pszCarrierAction, "CarrierRelease") == 0) { |
| | | m_master.carrierRelease(PTN); |
| | | LOGI("<CModel>CarrierRelease"); |
| | | m_master.carrierRelease(portIndex); |
| | | return CAACK_0; |
| | | } |
| | | |
| | | strErrorTxt = "rejected - invalid state"; |
| | | return CAACK_5; |
| | | LOGI("<Model>onCarrierAction %d, %s, %d, %d", DATAID, pszCarrierAction, pszCarrierId, PTN); |
| | | }; |
| | | listener.onPRJobMultiCreate = [&](void* pFrom, std::vector<SERVO::CProcessJob*>& pjs) -> int { |
| | | for (auto p : pjs) { |
| | | LOGI("<Model>onPRJobMultiCreate %s %s", p->id().c_str(), p->recipeSpec().c_str()); |
| | | } |
| | | |
| | | auto rejectAll = [&](uint32_t code, const std::string& msg) -> int { |
| | | LOGW("<Model>onPRJobMultiCreate rejected: %s", msg.c_str()); |
| | | for (auto p : pjs) { |
| | | if (p != nullptr) p->addIssue(code, msg); |
| | | } |
| | | return -1; |
| | | }; |
| | | |
| | | // å PJ 模å¼ï¼åªæ¥å 1 æ¡ä¸å½åæ å¨å¶ PJ |
| | | if (pjs.size() != 1) { |
| | | return rejectAll(1200, "Only 1 ProcessJob supported (single-PJ mode)"); |
| | | } |
| | | if (!m_master.isProcessJobsEmpty()) { |
| | | return rejectAll(1201, "ProcessJob exists, cannot create new in single-PJ mode"); |
| | | } |
| | | |
| | | int nRet = m_master.setProcessJobs(pjs); |
| | | auto processJobs = m_master.getProcessJobs(); |
| | | std::vector<SERVO::CVariable> vars; |
| | |
| | | vars.push_back(var); |
| | | } |
| | | |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PJQueued", vars); |
| | | m_hsmsPassive.requestEventReportSend_PJ_Queued(); |
| | | }); |
| | | return nRet; |
| | | }; |
| | | listener.onControlJobCreate = [&](void* pFrom, SERVO::CControlJob& controlJob) -> int { |
| | |
| | | CString strVarialbleFile; |
| | | strVarialbleFile.Format(_T("%s\\VariableList.txt"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | m_hsmsPassive.loadVarialbles((LPTSTR)(LPCTSTR)strVarialbleFile); |
| | | strVarialbleFile.Format(_T("%s\\DataVariableList.txt"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | m_hsmsPassive.loadDataVarialbles((LPTSTR)(LPCTSTR)strVarialbleFile); |
| | | strVarialbleFile.Format(_T("%s\\EquipmentConstantList.txt"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | m_hsmsPassive.loadEquipmentConstants((LPTSTR)(LPCTSTR)strVarialbleFile); |
| | | setControlState(m_currentControlState); |
| | | refreshDerivedSVs(); |
| | | m_hsmsPassive.init(this, "APP", 7000); |
| | | strVarialbleFile.Format(_T("%s\\ReportList.txt"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | m_hsmsPassive.loadReports((LPTSTR)(LPCTSTR)strVarialbleFile); |
| | | strVarialbleFile.Format(_T("%s\\CollectionEventList.txt"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | m_hsmsPassive.loadCollectionEvents((LPTSTR)(LPCTSTR)strVarialbleFile); |
| | | { |
| | | auto events = m_hsmsPassive.getCollectionEvents(); |
| | | std::vector<unsigned int> ceids; |
| | | ceids.reserve(events.size()); |
| | | for (auto e : events) { |
| | | if (e != nullptr) ceids.push_back(e->getEventId()); |
| | | } |
| | | m_master.setAllowedCeids(ceids); |
| | | } |
| | | strVarialbleFile.Format(_T("%s\\HsmsPassive.cache"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | m_hsmsPassive.loadCacheFromFile(strVarialbleFile); |
| | | LOGI("[BOOT][MODEL] HSMS config loaded, cost=%llu ms", |
| | | (unsigned long long)(GetTickCount64() - boot_model_begin)); |
| | | |
| | | |
| | | SERVO::MasterListener masterListener; |
| | | auto formatParamValue = [](const CParam& p) { |
| | | std::ostringstream oss; |
| | | oss.setf(std::ios::fixed); |
| | | oss << std::setprecision(4) << p.getDoubleValue(); |
| | | return oss.str(); |
| | | }; |
| | | masterListener.onMasterStateChanged = [&](void* pMaster, SERVO::MASTERSTATE state) -> void { |
| | | LOGI("<CModel>Master state changed(%d)", (int)state); |
| | | notify(RX_CODE_MASTER_STATE_CHANGED); |
| | | }; |
| | | masterListener.onControlJobChanged = [this](void* pMaster) { |
| | | (void)pMaster; |
| | | this->notifyControlJobChanged(); |
| | | }; |
| | | masterListener.onEqAlive = [&](void* pMaster, SERVO::CEquipment* pEquipment, BOOL bAlive) -> void { |
| | | LOGI("<CModel>Equipment onAlive:%s(%s).", pEquipment->getName().c_str(), |
| | |
| | | }; |
| | | masterListener.onEqVcrEventReport = [&](void* pMaster, SERVO::CEquipment* pEquipment, SERVO::CVcrEventReport* pReport) { |
| | | LOGE("<CModel>onEqVcrEventReport."); |
| | | if (pReport != nullptr) { |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("VCRPanelID", pReport->getGlassId().c_str()); |
| | | int nRet = m_hsmsPassive.requestEventReportSend_OCR_PanelID_Read(pReport->getVcrResult()); |
| | | if (nRet != ER_NOERROR) { |
| | | LOGE("<CModel>requestEventReportSend_OCR_PanelID_Read failed, ret=%d", nRet); |
| | | } |
| | | }); |
| | | } |
| | | }; |
| | | masterListener.onEqDataChanged = [&](void* pMaster, SERVO::CEquipment* pEquipment, int code) { |
| | | LOGE("<CModel>onEqDataChanged."); |
| | |
| | | }; |
| | | masterListener.onRobotTaskEvent = [&](void* pMaster, SERVO::CRobotTask* pTask, int code) { |
| | | if (pTask == nullptr) { |
| | | LOGE("<CModel>onRobotTaskEvent: ç©ºä»»å¡æéï¼å¿½ç¥äºä»¶ code=%d", code); |
| | | LOGE("<CModel>onRobotTaskEvent: ç©ºä»»å¡æéï¼å¿½ç¥äºä»¶ code=%d", code); |
| | | return; |
| | | } |
| | | |
| | | // ä»»å¡æè¿°ä¸ ID ç¨äºæ¥å¿ |
| | | // ä»»å¡æè¿°ä¸ ID ç¨äºæ¥å¿ |
| | | SERVO::CGlass* pGlass = (SERVO::CGlass*)pTask->getContext(); |
| | | const std::string& strDesc = pTask->getDescription(); |
| | | std::string strClassID; |
| | |
| | | } |
| | | } |
| | | |
| | | // æ¥å¿è¾åºä¸ç¶æå¤ç |
| | | // æ¥å¿è¾åºä¸ç¶æå¤ç |
| | | switch (code) { |
| | | case ROBOT_EVENT_CREATE: |
| | | LOGI("<CModel>onRobotTaskEvent: æ°ä»»å¡å建(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | LOGI("<CModel>onRobotTaskEvent: æ°ä»»å¡å建(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | break; |
| | | case ROBOT_EVENT_FINISH: |
| | | LOGI("<CModel>onRobotTaskEvent: ä»»å¡å®æ(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | LOGI("<CModel>onRobotTaskEvent: ä»»å¡å®æ(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | break; |
| | | case ROBOT_EVENT_ERROR: |
| | | LOGE("<CModel>onRobotTaskEvent: ä»»å¡é误(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | LOGE("<CModel>onRobotTaskEvent: ä»»å¡é误(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | break; |
| | | case ROBOT_EVENT_ABORT: |
| | | LOGE("<CModel>onRobotTaskEvent: ä»»å¡åæ¢(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | LOGE("<CModel>onRobotTaskEvent: ä»»å¡åæ¢(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | break; |
| | | case ROBOT_EVENT_RESTORE: |
| | | LOGE("<CModel>onRobotTaskEvent: ä»»å¡åæ¤(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | LOGE("<CModel>onRobotTaskEvent: ä»»å¡åæ¤(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | break; |
| | | default: |
| | | LOGE("<CModel>onRobotTaskEvent: æªç¥äºä»¶ code=%d, ä»»å¡=%s", code, strDesc.c_str()); |
| | | LOGE("<CModel>onRobotTaskEvent: æªç¥äºä»¶ code=%d, ä»»å¡=%s", code, strDesc.c_str()); |
| | | break; |
| | | } |
| | | |
| | | // å®å
¨æ ¼å¼åæ¶é´ |
| | | // å®å
¨æ ¼å¼åæ¶é´ |
| | | auto format_time = [](time_t t) -> std::string { |
| | | if (t <= 0 || t == _I64_MIN || t == _I64_MAX) { |
| | | return ""; |
| | | } |
| | | |
| | | // ä½¿ç¨ localtime_s ç¡®ä¿çº¿ç¨å®å
¨ |
| | | // ä½¿ç¨ localtime_s ç¡®ä¿çº¿ç¨å®å
¨ |
| | | tm tmBuf{}; |
| | | errno_t err = localtime_s(&tmBuf, &t); |
| | | if (err != 0 || tmBuf.tm_mon < 0 || tmBuf.tm_mon > 11) { |
| | | return ""; |
| | | } |
| | | |
| | | // æ ¼å¼åæ¶é´å符串 |
| | | // æ ¼å¼åæ¶é´å符串 |
| | | char buf[64] = {}; |
| | | strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tmBuf); |
| | | return std::string(buf); |
| | | }; |
| | | |
| | | // æé TransferData æ°æ®ç»æ |
| | | // æé TransferData æ°æ®ç»æ |
| | | TransferData data; |
| | | data.strClassID = strClassID; |
| | | data.strCreateTime = format_time(pTask->getCreateTime()); |
| | |
| | | data.strEndTime = format_time(pTask->getFinishTime()); |
| | | data.strDescription = pTask->getSimpleDescription(); |
| | | |
| | | // ç¶ææ å° |
| | | // ç¶ææ å° |
| | | static const char* STATUS_STR[] = { |
| | | "Ready", "Running", "Picking", "Picked", "Placing", "Restoring", "Error", "Abort", "Restored", "Completed" |
| | | }; |
| | |
| | | data.strStatus = "Unknown"; |
| | | } |
| | | |
| | | // åå
¥æ°æ®åº |
| | | // åå
¥æ°æ®åº |
| | | if (code == ROBOT_EVENT_FINISH || code == ROBOT_EVENT_ERROR |
| | | || code == ROBOT_EVENT_ABORT || code == ROBOT_EVENT_RESTORE) { |
| | | int nRecordId = 0; |
| | | TransferManager::getInstance().addTransferRecord(data, nRecordId); |
| | | LOGI("<CModel>onRobotTaskEvent: ä»»å¡è®°å½å·²ä¿åï¼RecordID=%d", nRecordId); |
| | | LOGI("<CModel>onRobotTaskEvent: ä»»å¡è®°å½å·²ä¿åï¼RecordID=%d", nRecordId); |
| | | } |
| | | notifyPtrAndInt(RX_CODE_EQ_ROBOT_TASK, pTask, nullptr, code); |
| | | |
| | | }; |
| | | masterListener.onJobReceived = [&](void* pMaster, SERVO::CEquipment* pEquipment, int port, SERVO::CJobDataS* pJobDataS) { |
| | | (void)pMaster; |
| | | (void)port; |
| | | if (pEquipment == nullptr || pJobDataS == nullptr) return; |
| | | { |
| | | const std::string& g1 = pJobDataS->getGlass1Id(); |
| | | const std::string& g2 = pJobDataS->getGlass2Id(); |
| | | std::string glassId; |
| | | if (!g1.empty() && !g2.empty()) { |
| | | glassId = g1 + "+" + g2; |
| | | } |
| | | else if (!g1.empty()) { |
| | | glassId = g1; |
| | | } |
| | | else { |
| | | glassId = g2; |
| | | } |
| | | const int slotNo = pJobDataS->getTargetSlotNo(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str()); |
| | | m_hsmsPassive.setVariableValue("SubEqpSlot", slotNo); |
| | | m_hsmsPassive.setVariableValue("MaterialId", glassId.c_str()); |
| | | m_hsmsPassive.requestEventReportSend("GlassReceivedJob"); |
| | | }); |
| | | } |
| | | const int eqId = pEquipment->getID(); |
| | | const int recipeId = pJobDataS->getMasterRecipe(); |
| | | std::string recipe = RecipeManager::getInstance().getPPIDById(recipeId); |
| | | if (recipe.empty()) { |
| | | recipe = std::to_string(recipeId); |
| | | } |
| | | const std::string prev = pEquipment->getCurrentRecipe(); |
| | | if (recipe.empty() || recipe == prev) { |
| | | pEquipment->setCurrentRecipe(recipe); |
| | | return; |
| | | } |
| | | pEquipment->setCurrentRecipe(recipe); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str()); |
| | | m_hsmsPassive.setVariableValue("EQPPExecName", recipe.c_str()); |
| | | m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str()); |
| | | const char* recipeVid = nullptr; |
| | | switch (eqId) { |
| | | case EQ_ID_Bonder1: recipeVid = "Bonder1CurrentRecipe"; break; |
| | | case EQ_ID_Bonder2: recipeVid = "Bonder2CurrentRecipe"; break; |
| | | case EQ_ID_VACUUMBAKE: recipeVid = "VacuumBakeCurrentRecipe"; break; |
| | | case EQ_ID_BAKE_COOLING: recipeVid = "BakeCoolingCurrentRecipe"; break; |
| | | case EQ_ID_MEASUREMENT: recipeVid = "MeasurementCurrentRecipe"; break; |
| | | case EQ_ID_EFEM: recipeVid = "EFEMCurrentRecipe"; break; |
| | | default: break; |
| | | } |
| | | if (recipeVid != nullptr) { |
| | | m_hsmsPassive.setVariableValue(recipeVid, recipe.c_str()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend("RecipeChanged"); |
| | | }); |
| | | }; |
| | | masterListener.onJobSentOut = [&](void* pMaster, SERVO::CEquipment* pEquipment, int port, SERVO::CJobDataS* pJobDataS) { |
| | | (void)pMaster; |
| | | (void)port; |
| | | if (pEquipment == nullptr || pJobDataS == nullptr) return; |
| | | const std::string& g1 = pJobDataS->getGlass1Id(); |
| | | const std::string& g2 = pJobDataS->getGlass2Id(); |
| | | std::string glassId; |
| | | if (!g1.empty() && !g2.empty()) { |
| | | glassId = g1 + "+" + g2; |
| | | } |
| | | else if (!g1.empty()) { |
| | | glassId = g1; |
| | | } |
| | | else { |
| | | glassId = g2; |
| | | } |
| | | const int slotNo = pJobDataS->getSourceSlotNo(); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str()); |
| | | m_hsmsPassive.setVariableValue("SubEqpSlot", slotNo); |
| | | m_hsmsPassive.setVariableValue("MaterialId", glassId.c_str()); |
| | | m_hsmsPassive.requestEventReportSend("GlassSentOutJob"); |
| | | }); |
| | | }; |
| | | masterListener.onLoadPortStatusChanged = [&] (void* pMaster, SERVO::CEquipment* pEquipment, short status, __int64 data) { |
| | | LOGE("<CModel>onLoadPortStatusChanged. status = %d", status); |
| | | if (status == PORT_INUSE) { |
| | | 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; |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | |
| | | // Unified PortStateChange event + SV maintenance |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("CarrierID", pLoadPort->getCassetteId().c_str()); |
| | | const unsigned int portIndex = pLoadPort->getIndex() + 1; |
| | | char stateVid[64] = {0}; |
| | | char modeVid[64] = {0}; |
| | | sprintf_s(stateVid, "PortTransferState_P%u", portIndex); |
| | | sprintf_s(modeVid, "AccessMode_P%u", portIndex); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue(stateVid, (__int64)status); |
| | | m_hsmsPassive.setVariableValue(modeVid, (__int64)pLoadPort->getPortMode()); |
| | | m_hsmsPassive.setVariableValue("PortId", pLoadPort->getID()); |
| | | m_hsmsPassive.setVariableValue("PortState", (__int64)status); |
| | | m_hsmsPassive.requestEventReportSend("PortStateChange"); |
| | | }); |
| | | } |
| | | |
| | | if (status == PORT_INUSE) { |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pLoadPort != nullptr) { |
| | | const unsigned int portIndex = pLoadPort->getIndex() + 1; |
| | | char carrierVid[64] = {0}; |
| | | sprintf_s(carrierVid, "CarrierID_P%u", portIndex); |
| | | m_hsmsPassive.setVariableValue(carrierVid, 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(); |
| | | }); |
| | | } |
| | | else if (status == PORT_BLOCKED) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("BlockedPortId", pLoadPort->getID()); |
| | | m_hsmsPassive.setVariableValue("PortId", pLoadPort->getID()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_Port_Blocked(); |
| | | }); |
| | | } |
| | | else if (status == PORT_LOAD_READY) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("LoadReadyPortId", pLoadPort->getID()); |
| | | m_hsmsPassive.setVariableValue("PortId", pLoadPort->getID()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_Port_Load_Ready(); |
| | | }); |
| | | } |
| | | else if (status == PORT_UNLOAD_READY) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("UnloadReadyPortId", pLoadPort->getID()); |
| | | m_hsmsPassive.setVariableValue("PortId", pLoadPort->getID()); |
| | | if (prevStatus == PORT_INUSE) { |
| | | m_hsmsPassive.setVariableValue("PortId", pLoadPort->getID()); |
| | | m_hsmsPassive.requestEventReportSend_Port_Ready_To_Release(); |
| | | } |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_Port_Unload_Ready(); |
| | | }); |
| | | } |
| | | else if (status == PORT_EMPTY) { |
| | | SERVO::CLoadPort* pLoadPort = dynamic_cast<SERVO::CLoadPort*>(pEquipment); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pLoadPort != nullptr) { |
| | | m_hsmsPassive.setVariableValue("PortId", pLoadPort->getID()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend_LoadPortNotAssoc(); |
| | | }); |
| | | } |
| | | notifyPtr(RX_CODE_LOADPORT_STATUS_CHANGED, pEquipment); |
| | | }; |
| | | masterListener.onProcessStateChanged = [&](void* pMaster, SERVO::CEquipment* pEquipment, int slotNo, SERVO::PROCESS_STATE prevState, SERVO::PROCESS_STATE state) { |
| | | (void)pMaster; |
| | | const int eqId = pEquipment ? pEquipment->getID() : 0; |
| | | |
| | | // ä¿æåä¸éèå´å
ï¼æ´æ°æé SV 并便¬¡ä¸æ¥ï¼ä¿è¯ set+send ååæ§ |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | // Timestamp VID (Clock, VID=500) for all related reports. |
| | | m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str()); |
| | | |
| | | // Common payload VIDs for SubEqp/Unit |
| | | if (pEquipment != nullptr) { |
| | | m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str()); |
| | | } |
| | | m_hsmsPassive.setVariableValue("SubEqpSlot", slotNo); |
| | | |
| | | // ProcessStateChanged (equipment-level): update SVs 700/701, then report CEID=700 |
| | | m_hsmsPassive.setVariableValue("PreviousProcessState", (__int64)prevState); |
| | | m_hsmsPassive.setVariableValue("CurrentProcessState", (__int64)state); |
| | | m_hsmsPassive.requestEventReportSend("ProcessStateChanged"); |
| | | |
| | | // SubEqp events (per equipment, ignore slot distinction except payload) |
| | | static std::map<int, SERVO::PROCESS_STATE> s_prevSubEqpState; |
| | | const auto prevEqState = s_prevSubEqpState[eqId]; |
| | | if (prevEqState != state) { |
| | | // state change |
| | | m_hsmsPassive.requestEventReportSend("SubEqpStateChange"); |
| | | } |
| | | if (state == SERVO::PROCESS_STATE::Processing) { |
| | | m_hsmsPassive.requestEventReportSend_SubEqpStart(); |
| | | } |
| | | else if (state == SERVO::PROCESS_STATE::Complete) { |
| | | m_hsmsPassive.requestEventReportSend_SubEqpEnd(); |
| | | } |
| | | s_prevSubEqpState[eqId] = state; |
| | | |
| | | // Unit events (per equipment slot) |
| | | static std::map<int, std::map<int, SERVO::PROCESS_STATE>> s_prevUnitState; |
| | | const auto prevUnitState = s_prevUnitState[eqId][slotNo]; |
| | | if (prevUnitState != state) { |
| | | m_hsmsPassive.requestEventReportSend("UnitStateChange"); |
| | | if (state == SERVO::PROCESS_STATE::Processing) { |
| | | m_hsmsPassive.requestEventReportSend("UnitStart"); |
| | | } |
| | | else if (state == SERVO::PROCESS_STATE::Complete) { |
| | | m_hsmsPassive.requestEventReportSend("UnitEnd"); |
| | | } |
| | | s_prevUnitState[eqId][slotNo] = state; |
| | | } |
| | | }); |
| | | }; |
| | | masterListener.onSVDataReport = [&](void* pMaster, SERVO::CEquipment* pEquipment, const std::vector<CParam>& params) { |
| | | (void)pMaster; |
| | | const int eqId = pEquipment ? pEquipment->getID() : 0; |
| | | |
| | | auto sendSv = [&](const auto& vidMap, const char* evName) { |
| | | const size_t count = (std::min)(params.size(), vidMap.size()); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pEquipment != nullptr) { |
| | | m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str()); |
| | | } |
| | | m_hsmsPassive.setVariableValue("SubEqpSlot", 0); |
| | | m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str()); |
| | | for (size_t idx = 0; idx < count; ++idx) { |
| | | const std::string val = formatParamValue(params[idx]); |
| | | m_hsmsPassive.setVariableValue(std::to_string(vidMap[idx]).c_str(), val.c_str()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend(evName); |
| | | }); |
| | | }; |
| | | |
| | | if (eqId == EQ_ID_Bonder1 || eqId == EQ_ID_Bonder2) { |
| | | static constexpr std::array<int, 19> vids = { |
| | | 6000,6001,6002,6003,6004,6005,6006,6007,6008,6009, |
| | | 6010,6011,6012,6013,6014,6015,6016,6017,6018 |
| | | }; |
| | | sendSv(vids, "BonderSVData"); |
| | | } |
| | | else if (eqId == EQ_ID_VACUUMBAKE) { |
| | | static constexpr std::array<int, 18> vids = { |
| | | 6200,6201,6202,6203,6204,6205,6206,6207,6208, |
| | | 6209,6210,6211,6212,6213,6214,6215,6216,6217 |
| | | }; |
| | | sendSv(vids, "VacuumBakeSVData"); |
| | | } |
| | | else if (eqId == EQ_ID_BAKE_COOLING) { |
| | | static constexpr std::array<int, 20> vids = { |
| | | 6400,6401,6402,6403,6404,6405,6406,6407,6408,6409, |
| | | 6410,6411,6412,6413,6414,6415,6416,6417,6418,6419 |
| | | }; |
| | | sendSv(vids, "BakeCoolingSVData"); |
| | | } |
| | | else if (eqId == EQ_ID_MEASUREMENT) { |
| | | static constexpr std::array<int, 2> vids = { 6600, 6601 }; |
| | | sendSv(vids, "MeasurementSVData"); |
| | | } |
| | | }; |
| | | masterListener.onProcessDataReport = [&](void* pMaster, SERVO::CEquipment* pEquipment, const std::vector<CParam>& params) { |
| | | (void)pMaster; |
| | | const int eqId = pEquipment ? pEquipment->getID() : 0; |
| | | |
| | | auto sendProcess = [&](const auto& vidMap, const char* evName) { |
| | | const size_t count = (std::min)(params.size(), vidMap.size()); |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | if (pEquipment != nullptr) { |
| | | m_hsmsPassive.setVariableValue("SubEqpName", pEquipment->getName().c_str()); |
| | | } |
| | | m_hsmsPassive.setVariableValue("SubEqpSlot", 0); |
| | | m_hsmsPassive.setVariableValue("Clock", CToolUnits::getCurrentTimeString().c_str()); |
| | | for (size_t idx = 0; idx < count; ++idx) { |
| | | const std::string val = formatParamValue(params[idx]); |
| | | m_hsmsPassive.setVariableValue(std::to_string(vidMap[idx]).c_str(), val.c_str()); |
| | | } |
| | | m_hsmsPassive.requestEventReportSend(evName); |
| | | }); |
| | | }; |
| | | |
| | | if (eqId == EQ_ID_Bonder1 || eqId == EQ_ID_Bonder2) { |
| | | static constexpr std::array<int, 22> vids = { |
| | | 6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110, |
| | | 6111,6112,6113,6114,6115,6116,6117,6118,6119,6120,6121 |
| | | }; |
| | | sendProcess(vids, "BonderProcessData"); |
| | | } |
| | | else if (eqId == EQ_ID_VACUUMBAKE) { |
| | | static constexpr std::array<int, 5> vids = { 6300,6301,6302,6303,6304 }; |
| | | sendProcess(vids, "VacuumBakeProcessData"); |
| | | } |
| | | else if (eqId == EQ_ID_BAKE_COOLING) { |
| | | static constexpr std::array<int, 4> vids = { 6500,6501,6502,6503 }; |
| | | sendProcess(vids, "BakeCoolingProcessData"); |
| | | } |
| | | else if (eqId == EQ_ID_MEASUREMENT) { |
| | | static constexpr std::array<int, 4> vids = { 6700,6701,6702,6703 }; |
| | | sendProcess(vids, "MeasurementProcessData"); |
| | | } |
| | | }; |
| | | masterListener.onCTRoundEnd = [&](void* pMaster, int round) { |
| | | m_configuration.setContinuousTransferCount(round); |
| | | }; |
| | | masterListener.onCjStart = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("CJStartID", ((SERVO::CControlJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_CJ_Start(); |
| | | }); |
| | | }; |
| | | masterListener.onCjEnd = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("CJEndID", ((SERVO::CControlJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_CJ_End(); |
| | | }); |
| | | |
| | | // ç»æ¹ï¼ä¿åControlJob |
| | | // ç»æ¹ï¼ä¿åControlJob |
| | | // |
| | | }; |
| | | masterListener.onPjStart = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PJStartID", ((SERVO::CProcessJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_PJ_Start(); |
| | | }); |
| | | }; |
| | | masterListener.onPjEnd = [&](void* pMaster, void* pj) { |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PJEndID", ((SERVO::CProcessJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_PJ_End(); |
| | | }); |
| | | }; |
| | | masterListener.onPanelStart = [&](void* pMaster, void* pPanel) { |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PanelStartID", ((SERVO::CGlass*)pPanel)->getID().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_Panel_Start(); |
| | | }); |
| | | }; |
| | | masterListener.onPanelEnd = [&](void* pMaster, void* pPanel) { |
| | | m_hsmsPassive.withVariableLock([&] { |
| | | m_hsmsPassive.setVariableValue("PanelEndID", ((SERVO::CGlass*)pPanel)->getID().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_Panel_End(); |
| | | // Placeholder payload to match log shape: EV_PROCESS_DATA_REPORT can carry a single A-string (may be empty). |
| | | m_hsmsPassive.setVariableValue("ProcessDataReportText", ""); |
| | | m_hsmsPassive.requestEventReportSend_ProcessDataReport(); |
| | | }); |
| | | auto& db = GlassLogDb::Instance(); |
| | | db.insertFromCGlass((*(SERVO::CGlass*)pPanel)); |
| | | SERVO::CGlass* pBuddy = ((SERVO::CGlass*)pPanel)->getBuddy(); |
| | |
| | | m_master.setContinuousTransferCount(m_configuration.getContinuousTransferCount()); |
| | | |
| | | |
| | | // master 设置ç¼åæä»¶ |
| | | // master 设置ç¼åæä»¶ |
| | | CString strMasterDataFile; |
| | | strMasterDataFile.Format(_T("%s\\Master.dat"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | m_master.setCacheFilepath((LPTSTR)(LPCTSTR)strMasterDataFile); |
| | | m_master.setCompareMapsBeforeProceeding(m_configuration.isCompareMapsBeforeProceeding()); |
| | | m_master.setJobMode(m_configuration.isJobMode()); |
| | | |
| | | // å æªJob |
| | | // å æªJob |
| | | strMasterDataFile.Format(_T("%s\\MasterState.dat"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | std::string strPath = std::string((LPTSTR)(LPCTSTR)strMasterDataFile); |
| | | m_master.setStateFile(strPath); |
| | | |
| | | |
| | | |
| | | // å è½½è¦åä¿¡æ¯ |
| | | // å è½½è¦åä¿¡æ¯ |
| | | AlarmManager& alarmManager = AlarmManager::getInstance(); |
| | | char szBuffer[MAX_PATH]; |
| | | sprintf_s(szBuffer, MAX_PATH, "%s\\AlarmList.csv", (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | alarmManager.readAlarmFile(szBuffer); |
| | | LOGI("[BOOT][MODEL] Alarm list loaded, cost=%llu ms", |
| | | (unsigned long long)(GetTickCount64() - boot_model_begin)); |
| | | |
| | | |
| | | // Glassæ°æ®åº |
| | | // Glassæ°æ®åº |
| | | strLogDir.Format(_T("%s\\db\\process.db"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | std::string path((LPTSTR)(LPCTSTR)strLogDir); |
| | | GlassLogDb::Init(path); |
| | | |
| | | |
| | | LOGI("[BOOT][MODEL] init finished, total cost=%llu ms", |
| | | (unsigned long long)(GetTickCount64() - boot_model_begin)); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | #include "HsmsPassive.h" |
| | | #include "CMaster.h" |
| | | #include "CGlassPool.h" |
| | | #include <cstdint> |
| | | #include <string> |
| | | |
| | | enum class ControlState : uint8_t { |
| | | OfflineEquipment = 0, |
| | | OfflineAttempt = 1, |
| | | Online = 2, |
| | | OfflineHost = 3, |
| | | OnlineLocal = 4, |
| | | OnlineRemote = 5, |
| | | }; |
| | | |
| | | class CModel |
| | | { |
| | |
| | | void setPortEnable(unsigned int index, BOOL bEnable); |
| | | int init(); |
| | | int term(); |
| | | |
| | | ControlState getControlState() const noexcept { return m_currentControlState; } |
| | | void setControlState(ControlState newState); |
| | | bool raiseSoftAlarm(int alarmId, |
| | | const std::string& desc = "", |
| | | int level = -1, |
| | | int deviceId = 0, |
| | | int unitId = 0, |
| | | const char* deviceName = "Software", |
| | | const char* unitName = "App"); |
| | | void clearSoftAlarm(int alarmId, int deviceId = 0, int unitId = 0); |
| | | |
| | | private: |
| | | void refreshDerivedSVs(); |
| | | void notifyControlJobChanged(); |
| | | |
| | | public: |
| | | int notify(int code); |
| | |
| | | IObservableEmitter* m_pObservableEmitter; |
| | | CString m_strWorkDir; |
| | | CString m_strDataDir; |
| | | }; |
| | | |
| | | private: |
| | | ControlState m_currentControlState{ ControlState::OfflineEquipment }; |
| | | }; |
| | |
| | | // éåæ°æ®å¹¶æå
¥å°CListCtrlä¸ |
| | | for (int i = 0; i < static_cast<int>(vecRecipe.size()); ++i) { |
| | | const RecipeInfo& recipe = vecRecipe[i]; |
| | | // åç¨åºè¦æ±PPIDæåé
æ¹ï¼å
注é |
| | | /* |
| | | if (recipe.vecDeviceList.empty() || recipe.vecDeviceList.size() > 6){ |
| | | continue; |
| | | } |
| | | */ |
| | | |
| | | m_listPPID.InsertItem(i, _T("")); // 第0åç©ºç½ |
| | | |
| | |
| | | |
| | | void CPageRecipe::OnBnClickedButtonNew() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | //CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_EQUIPMENT); |
| | | //int nSel = pComboBox->GetCurSel(); |
| | | //SERVO::CEquipment* pEq = (SERVO::CEquipment*)pComboBox->GetItemDataPtr(nSel); |
| | | //if (pEq == nullptr) { |
| | | // return; |
| | | //} |
| | | int rc = UX_CanExecute(L"recipe"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | UX_RecordAction(L"recipe"); |
| | | |
| | | CRecipeDeviceBindDlg dlg(this); |
| | | if (dlg.DoModal() == IDOK) { |
| | |
| | | |
| | | void CPageRecipe::OnBnClickedButtonModify() |
| | | { |
| | | int rc = UX_CanExecute(L"recipe"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | UX_RecordAction(L"recipe"); |
| | | |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_EQUIPMENT); |
| | | if (pComboBox == nullptr || !::IsWindow(pComboBox->m_hWnd)) { |
| | |
| | | |
| | | void CPageRecipe::OnBnClickedButtonDelete() |
| | | { |
| | | int rc = UX_CanExecute(L"recipe"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | UX_RecordAction(L"recipe"); |
| | | |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | POSITION pos = m_listPPID.GetFirstSelectedItemPosition(); |
| | | if (!pos) { |
| | |
| | | |
| | | void CPageRecipe::OnBnClickedButtonDeleteAll() |
| | | { |
| | | int rc = UX_CanExecute(L"recipe"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | UX_RecordAction(L"recipe"); |
| | | |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | if (IDYES != AfxMessageBox(_T("ç¡®å®è¦å é¤å
¨é¨é
æ¹è®°å½åï¼"), MB_YESNO | MB_ICONWARNING)) { |
| | | return; |
| | |
| | | { |
| | | int selPort = (0 <= m_nCurSelPort && m_nCurSelPort <= 3) ? m_nCurSelPort |
| | | : m_comboPort.GetCurSel(); |
| | | if (selPort < 0 || selPort >= 4) return; |
| | | m_pPort[selPort]->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr); |
| | | if (selPort < 0 || selPort >= 4) { |
| | | LOGE("ProcessStart invalid port index: %d", selPort); |
| | | return; |
| | | } |
| | | |
| | | SERVO::CLoadPort* pPort = m_pPort[selPort]; |
| | | if (pPort == nullptr) { |
| | | LOGE("ProcessStart port pointer is null, index: %d", selPort); |
| | | return; |
| | | } |
| | | |
| | | constexpr short cmd = CCC_PROCESS_START; |
| | | LOGI("ProcessStart request: port=%d, cmd=%d", selPort + 1, cmd); |
| | | int ret = pPort->sendCassetteCtrlCmd(cmd, nullptr, 0, 0, 0, nullptr, |
| | | [selPort](int code) -> int { |
| | | if (code == WOK) { |
| | | LOGI("ProcessStart write complete: port=%d, code=WOK", selPort + 1); |
| | | } |
| | | else { |
| | | LOGE("ProcessStart write failed: port=%d, code=%d", selPort + 1, code); |
| | | } |
| | | return 0; |
| | | }); |
| | | if (ret != 0) { |
| | | LOGE("ProcessStart sendCassetteCtrlCmd immediate failure: port=%d, ret=%d", selPort + 1, ret); |
| | | } |
| | | else { |
| | | LOGI("ProcessStart sendCassetteCtrlCmd dispatched: port=%d", selPort + 1); |
| | | } |
| | | } |
| | | |
| | | void CPortConfigurationDlg::OnBnClickedButtonProcessCancel() |
| | | { |
| | | int selPort = (0 <= m_nCurSelPort && m_nCurSelPort <= 3) ? m_nCurSelPort |
| | | : m_comboPort.GetCurSel(); |
| | | if (selPort < 0 || selPort >= 4) return; |
| | | m_pPort[selPort]->sendCassetteCtrlCmd(CCC_PROCESS_CANCEL, nullptr, 0, 0, 0, nullptr, nullptr); |
| | | if (selPort < 0 || selPort >= 4) { |
| | | LOGE("ProcessCancel invalid port index: %d", selPort); |
| | | return; |
| | | } |
| | | |
| | | SERVO::CLoadPort* pPort = m_pPort[selPort]; |
| | | if (pPort == nullptr) { |
| | | LOGE("ProcessCancel port pointer is null, index: %d", selPort); |
| | | return; |
| | | } |
| | | |
| | | constexpr short cmd = CCC_PROCESS_CANCEL; |
| | | LOGI("ProcessCancel request: port=%d, cmd=%d", selPort + 1, cmd); |
| | | int ret = pPort->sendCassetteCtrlCmd(cmd, nullptr, 0, 0, 0, nullptr, |
| | | [selPort](int code) -> int { |
| | | if (code == WOK) { |
| | | LOGI("ProcessCancel write complete: port=%d, code=WOK", selPort + 1); |
| | | } |
| | | else { |
| | | LOGE("ProcessCancel write failed: port=%d, code=%d", selPort + 1, code); |
| | | } |
| | | return 0; |
| | | }); |
| | | if (ret != 0) { |
| | | LOGE("ProcessCancel sendCassetteCtrlCmd immediate failure: port=%d, ret=%d", selPort + 1, ret); |
| | | } |
| | | else { |
| | | LOGI("ProcessCancel sendCassetteCtrlCmd dispatched: port=%d", selPort + 1); |
| | | } |
| | | } |
| | |
| | | return m_issues; |
| | | } |
| | | |
| | | void CProcessJob::addIssue(uint32_t code, const std::string& msg) |
| | | { |
| | | m_issues.push_back({ code, msg }); |
| | | } |
| | | |
| | | bool CProcessJob::validate(const IResourceView& rv) |
| | | { |
| | | m_issues.clear(); |
| | |
| | | auto add = [&](uint32_t code, std::string msg) { |
| | | m_issues.push_back({ code, std::move(msg) }); |
| | | }; |
| | | |
| | | if (!rv.isProcessJobsEmpty()) { |
| | | add(1000, "ProcessJobs Conflict!"); |
| | | } |
| | | |
| | | // ââ åºæ¬ / æ è¯ ââ |
| | | if (m_pjId.empty()) add(1001, "PJID empty"); |
| | |
| | | // è¿åé®é¢æ¸
åï¼ç©º=éè¿ï¼ |
| | | bool validate(const IResourceView& rv); |
| | | const std::vector<ValidationIssue>& issues() const; |
| | | void addIssue(uint32_t code, const std::string& msg); |
| | | |
| | | // ââ ç¶ææºï¼å¸¦å®å«ï¼ââ |
| | | bool queue(); // NoState -> Queued |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #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, " |
| | | "IFNULL(strftime('%Y-%m-%d %H:%M:%S', t_start, 'localtime'), '')," |
| | | "IFNULL(strftime('%Y-%m-%d %H:%M:%S', t_end, 'localtime'), '') " |
| | | "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; |
| | | long long maxTaktSeconds = -1; |
| | | }; |
| | | 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 char* sStart = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3)); |
| | | const char* sEnd = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 4)); |
| | | |
| | | 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; |
| | | |
| | | std::chrono::system_clock::time_point tpStart{}, tpEnd{}; |
| | | if (TryParseLocalTime(sStart ? sStart : "", tpStart) && TryParseLocalTime(sEnd ? sEnd : "", tpEnd) && tpEnd > tpStart) { |
| | | const auto secs = std::chrono::duration_cast<std::chrono::seconds>(tpEnd - tpStart).count(); |
| | | if (secs > agg.maxTaktSeconds) agg.maxTaktSeconds = secs; |
| | | } |
| | | } |
| | | else if (rc == SQLITE_DONE) { |
| | | break; |
| | | } |
| | | else { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | sqlite3_finalize(stmt); |
| | | sqlite3_close(db); |
| | | |
| | | out.pairsTotal = static_cast<long long>(pairs.size()); |
| | | long long sumTakt = 0; |
| | | long long cntTakt = 0; |
| | | for (const auto& kv : pairs) { |
| | | const auto& agg = kv.second; |
| | | if (agg.hasFail) out.pairsFail++; |
| | | else if (agg.hasPass) out.pairsPass++; |
| | | else out.pairsNoResult++; |
| | | |
| | | if (agg.maxTaktSeconds >= 0) { |
| | | sumTakt += agg.maxTaktSeconds; |
| | | cntTakt += 1; |
| | | } |
| | | } |
| | | const long long denom = out.pairsPass + out.pairsFail; |
| | | out.yield = (denom > 0) ? (static_cast<double>(out.pairsPass) / static_cast<double>(denom)) : 0.0; |
| | | out.taktSamplePairs = cntTakt; |
| | | out.avgTaktSeconds = (cntTakt > 0) ? (static_cast<double>(sumTakt) / static_cast<double>(cntTakt)) : 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>Takt: avg=%.1fs, samples=%lld", s.output.avgTaktSeconds, s.output.taktSamplePairs); |
| | | 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()); |
| | | } |
| | | } |
| | | |
| | | bool ProductionStats::ComputeDayNightSummaries(CConfiguration& config, ProductionShiftSummary& outDay, ProductionShiftSummary& outNight) |
| | | { |
| | | ProductionShiftSummary cur; |
| | | if (!ComputeCurrentShiftSummary(config, cur)) return false; |
| | | |
| | | // Determine previous adjacent window for the other shift. |
| | | ProductionShiftSummary other = cur; |
| | | if (cur.window.type == ProductionShiftType::Day) { |
| | | other.window.type = ProductionShiftType::Night; |
| | | other.window.end = cur.window.start; |
| | | other.window.start = cur.window.start - (cur.window.end - cur.window.start); |
| | | } |
| | | else { |
| | | other.window.type = ProductionShiftType::Day; |
| | | other.window.end = cur.window.start; |
| | | other.window.start = cur.window.start - (cur.window.end - cur.window.start); |
| | | } |
| | | other.window.startLocal = FormatLocal(other.window.start); |
| | | other.window.endLocal = FormatLocal(other.window.end); |
| | | other.window.startUtcIso = FormatUtcIso(other.window.start); |
| | | other.window.endUtcIso = FormatUtcIso(other.window.end); |
| | | |
| | | other.output = ProductionOutputSummary{}; |
| | | other.alarms = ProductionAlarmSummary{}; |
| | | other.transfers = ProductionTransferSummary{}; |
| | | ComputeOutputFromProcessDb(other.window, other.output); |
| | | ComputeAlarmSummaryFromDb(other.window, other.alarms); |
| | | ComputeTransferSummaryFromDb(other.window, other.transfers); |
| | | |
| | | if (cur.window.type == ProductionShiftType::Day) { |
| | | outDay = std::move(cur); |
| | | outNight = std::move(other); |
| | | } |
| | | else { |
| | | outNight = std::move(cur); |
| | | outDay = std::move(other); |
| | | } |
| | | return true; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #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 |
| | | |
| | | // Average takt time derived from glass_log.t_start/t_end (per pair, seconds) |
| | | double avgTaktSeconds = 0.0; |
| | | long long taktSamplePairs = 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); |
| | | |
| | | // Computes "current shift" and its adjacent other shift, so UI can always show Day+Night numbers. |
| | | // - If current is Day: day=current day shift, night=previous night shift. |
| | | // - If current is Night: night=current night shift, day=previous day shift. |
| | | static bool ComputeDayNightSummaries(CConfiguration& config, ProductionShiftSummary& outDay, ProductionShiftSummary& outNight); |
| | | }; |
| | |
| | | |
| | | // Servo.cpp : å®ä¹åºç¨ç¨åºçç±»è¡ä¸ºã |
| | |  |
| | | // Servo.cpp : å®ä¹åºç¨ç¨åºçç±»è¡ä¸ºã |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | |
| | | #include "MapPosWnd.h" |
| | | #include "HmTab.h" |
| | | #include "CControlJobManagerDlg.h" |
| | | #include "ToolUnits.h" |
| | | #include "CUserManager2.h" |
| | | #include "AccordionWnd.h" |
| | | |
| | | |
| | | // 声æå
¨å±åéï¼ç¨äºç®¡ç GDI+ åå§å |
| | | // 声æå
¨å±åéï¼ç¨äºç®¡ç GDI+ åå§å |
| | | ULONG_PTR g_diplusToken; |
| | | GdiplusStartupInput g_diplusStartupInput; |
| | | |
| | |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CServoApp æé |
| | | // CServoApp æé |
| | | |
| | | CServoApp::CServoApp() |
| | | { |
| | | // æ¯æéæ°å¯å¨ç®¡çå¨ |
| | | // æ¯æéæ°å¯å¨ç®¡çå¨ |
| | | m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; |
| | | |
| | | // TODO: 卿¤å¤æ·»å æé 代ç ï¼ |
| | | // å°ææéè¦çåå§åæ¾ç½®å¨ InitInstance ä¸ |
| | | // TODO: 卿¤å¤æ·»å æé 代ç ï¼ |
| | | // å°ææéè¦çåå§åæ¾ç½®å¨ InitInstance ä¸ |
| | | m_nVersionNumber = 8; |
| | | m_strVersionName = _T("1.0.08"); |
| | | } |
| | | |
| | | |
| | | // å¯ä¸çä¸ä¸ª CServoApp 对象 |
| | | // å¯ä¸çä¸ä¸ª CServoApp 对象 |
| | | |
| | | CServoApp theApp; |
| | | |
| | | |
| | | // CServoApp åå§å |
| | | // CServoApp åå§å |
| | | |
| | | BOOL CServoApp::InitInstance() |
| | | { |
| | | // TODO: è°ç¨ AfxInitRichEdit2() 以åå§å richedit2 åºã\n" // 妿ä¸ä¸ªè¿è¡å¨ Windows XP ä¸çåºç¨ç¨åºæ¸
åæå®è¦ |
| | | // ä½¿ç¨ ComCtl32.dll çæ¬ 6 ææ´é«çæ¬æ¥å¯ç¨å¯è§åæ¹å¼ï¼ |
| | | //åéè¦ InitCommonControlsEx()ã å¦åï¼å°æ æ³å建çªå£ã |
| | | // TODO: è°ç¨ AfxInitRichEdit2() 以åå§å richedit2 åºã\n" // 妿ä¸ä¸ªè¿è¡å¨ Windows XP ä¸çåºç¨ç¨åºæ¸
åæå®è¦ |
| | | // ä½¿ç¨ ComCtl32.dll çæ¬ 6 ææ´é«çæ¬æ¥å¯ç¨å¯è§åæ¹å¼ï¼ |
| | | //åéè¦ InitCommonControlsEx()ã å¦åï¼å°æ æ³å建çªå£ã |
| | | INITCOMMONCONTROLSEX InitCtrls; |
| | | InitCtrls.dwSize = sizeof(InitCtrls); |
| | | // å°å®è®¾ç½®ä¸ºå
æ¬ææè¦å¨åºç¨ç¨åºä¸ä½¿ç¨ç |
| | | // å
Œ
±æ§ä»¶ç±»ã |
| | | // å°å®è®¾ç½®ä¸ºå
æ¬ææè¦å¨åºç¨ç¨åºä¸ä½¿ç¨ç |
| | | // å
Œ
±æ§ä»¶ç±»ã |
| | | InitCtrls.dwICC = ICC_WIN95_CLASSES; |
| | | InitCommonControlsEx(&InitCtrls); |
| | | |
| | |
| | | |
| | | AfxEnableControlContainer(); |
| | | |
| | | // å建 shell 管çå¨ï¼ä»¥é²å¯¹è¯æ¡å
å« |
| | | // ä»»ä½ shell æ è§å¾æ§ä»¶æ shell å表è§å¾æ§ä»¶ã |
| | | // å建 shell 管çå¨ï¼ä»¥é²å¯¹è¯æ¡å
å« |
| | | // ä»»ä½ shell æ è§å¾æ§ä»¶æ shell å表è§å¾æ§ä»¶ã |
| | | CShellManager *pShellManager = new CShellManager; |
| | | |
| | | // æ¿æ´»âWindows Nativeâè§è§ç®¡çå¨ï¼ä»¥ä¾¿å¨ MFC æ§ä»¶ä¸å¯ç¨ä¸»é¢ |
| | | // æ¿æ´»âWindows Nativeâè§è§ç®¡çå¨ï¼ä»¥ä¾¿å¨ MFC æ§ä»¶ä¸å¯ç¨ä¸»é¢ |
| | | CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); |
| | | |
| | | // æ ååå§å |
| | | // 妿æªä½¿ç¨è¿äºåè½å¹¶å¸æåå° |
| | | // æç»å¯æ§è¡æä»¶ç大å°ï¼ååºç§»é¤ä¸å |
| | | // ä¸éè¦çç¹å®åå§åä¾ç¨ |
| | | // æ´æ¹ç¨äºåå¨è®¾ç½®ç注å表项 |
| | | // TODO: åºéå½ä¿®æ¹è¯¥åç¬¦ä¸²ï¼ |
| | | // ä¾å¦ä¿®æ¹ä¸ºå
¬å¸æç»ç»å |
| | | SetRegistryKey(_T("åºç¨ç¨åºå导çæçæ¬å°åºç¨ç¨åº")); |
| | | // æ ååå§å |
| | | // 妿æªä½¿ç¨è¿äºåè½å¹¶å¸æåå° |
| | | // æç»å¯æ§è¡æä»¶ç大å°ï¼ååºç§»é¤ä¸å |
| | | // ä¸éè¦çç¹å®åå§åä¾ç¨ |
| | | // æ´æ¹ç¨äºåå¨è®¾ç½®ç注å表项 |
| | | // TODO: åºéå½ä¿®æ¹è¯¥åç¬¦ä¸²ï¼ |
| | | // ä¾å¦ä¿®æ¹ä¸ºå
¬å¸æç»ç»å |
| | | SetRegistryKey(_T("åºç¨ç¨åºå导çæçæ¬å°åºç¨ç¨åº")); |
| | | |
| | | |
| | | // æ¬ç¨åºæä»¶ç®å½ |
| | | // æ¬ç¨åºæä»¶ç®å½ |
| | | TCHAR sDrive[_MAX_DRIVE]; |
| | | TCHAR sDir[_MAX_DIR]; |
| | | TCHAR sFilename[_MAX_FNAME], sAppFilename[_MAX_FNAME]; |
| | |
| | | m_model.setWorkDir((LPTSTR)(LPCTSTR)m_strAppDir); |
| | | |
| | | |
| | | // æ³¨åæ§ä»¶ |
| | | // ç¨æ·æ°æ®åºç®¡ç |
| | | CString strDir = m_strAppDir + _T("\\DB"); |
| | | CUserManager2::getInstance().init((LPTSTR)(LPCTSTR)strDir); |
| | | |
| | | |
| | | // æ³¨åæ§ä»¶ |
| | | CServoGraph::RegisterWndClass(); |
| | | CVerticalLine::RegisterWndClass(); |
| | | CHorizontalLine::RegisterWndClass(); |
| | | CEqsGraphWnd::RegisterWndClass(); |
| | | CMapPosWnd::RegisterWndClass(); |
| | | CHmTab::RegisterWndClass(); |
| | | CAccordionWnd::RegisterWndClass(); |
| | | |
| | | |
| | | // åå§åRxåº |
| | | // åå§åRxåº |
| | | RX_Init(); |
| | | HSMS_Initialize(); |
| | | |
| | | |
| | | // åå§å GDI+ |
| | | // åå§å GDI+ |
| | | InitGDIPlus(); |
| | | |
| | | |
| | | // åå§å MFC RichEdit æ§ä»¶ |
| | | // åå§å MFC RichEdit æ§ä»¶ |
| | | AfxInitRichEdit2(); |
| | | |
| | | |
| | | // åå§åæ¥è¦ç®¡çå¨ |
| | | // åå§åæ¥è¦ç®¡çå¨ |
| | | try { |
| | | if (!AlarmManager::getInstance().initAlarmTable()) { |
| | | AfxMessageBox("åå§åæ¥è¦ç®¡çå¨å¤±è´¥ï¼"); |
| | | AfxMessageBox("åå§åæ¥è¦ç®¡çå¨å¤±è´¥ï¼"); |
| | | return FALSE; |
| | | } |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("åå§åæ¥è¦ç®¡çå¨å¤±è´¥ï¼%s"), CString(ex.what())); |
| | | errorMsg.Format(_T("åå§åæ¥è¦ç®¡çå¨å¤±è´¥ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | return FALSE; |
| | | } |
| | | |
| | | // åå§åæ¬è¿è®°å½ç®¡çåº |
| | | // åå§åæ¬è¿è®°å½ç®¡çåº |
| | | try { |
| | | if (!TransferManager::getInstance().initTransferTable()) { |
| | | AfxMessageBox("åå§åæ¬è¿è®°å½ç®¡çåºè®¾ç½®å¤±è´¥ï¼"); |
| | | AfxMessageBox("åå§åæ¬è¿è®°å½ç®¡çåºè®¾ç½®å¤±è´¥ï¼"); |
| | | return FALSE; |
| | | } |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("åå§åæ¬è¿è®°å½ç®¡çåºè®¾ç½®å¤±è´¥ï¼%s"), CString(ex.what())); |
| | | errorMsg.Format(_T("åå§åæ¬è¿è®°å½ç®¡çåºè®¾ç½®å¤±è´¥ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | return FALSE; |
| | | } |
| | | |
| | | // åå§åè¿è¡æ¥å¿ç®¡çåº |
| | | // åå§åè¿è¡æ¥å¿ç®¡çåº |
| | | try { |
| | | if (!SystemLogManager::getInstance().initSystemLogTable()) { |
| | | AfxMessageBox("åå§åè¿è¡æ¥å¿ç®¡çåºå¤±è´¥ï¼"); |
| | | AfxMessageBox("åå§åè¿è¡æ¥å¿ç®¡çåºå¤±è´¥ï¼"); |
| | | return FALSE; |
| | | } |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("åå§åè¿è¡æ¥å¿ç®¡çåºå¤±è´¥ï¼%s"), CString(ex.what())); |
| | | errorMsg.Format(_T("åå§åè¿è¡æ¥å¿ç®¡çåºå¤±è´¥ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | return FALSE; |
| | | } |
| | | |
| | | // åå§åç¨æ·ç®¡çåº |
| | | // åå§åç¨æ·ç®¡çåº |
| | | try { |
| | | UserManager& userManager = UserManager::getInstance(); |
| | | #if !defined(_DEBUG) |
| | |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("åå§åç¨æ·ç®¡çåºå¤±è´¥ï¼%s"), CString(ex.what())); |
| | | errorMsg.Format(_T("åå§åç¨æ·ç®¡çåºå¤±è´¥ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | return FALSE; |
| | | } |
| | | |
| | | // åå§åé
æ¹ç®¡çåº |
| | | // åå§åé
æ¹ç®¡çåº |
| | | try { |
| | | if (!RecipeManager::getInstance().initRecipeTable()) { |
| | | AfxMessageBox("åå§åé
æ¹ç®¡çåºå¤±è´¥ï¼"); |
| | | AfxMessageBox("åå§åé
æ¹ç®¡çåºå¤±è´¥ï¼"); |
| | | return FALSE; |
| | | } |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("åå§åé
æ¹ç®¡çåºå¤±è´¥ï¼%s"), CString(ex.what())); |
| | | errorMsg.Format(_T("åå§åé
æ¹ç®¡çåºå¤±è´¥ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | return FALSE; |
| | | } |
| | |
| | | INT_PTR nResponse = dlg.DoModal(); |
| | | if (nResponse == IDOK) |
| | | { |
| | | // TODO: 卿¤æ¾ç½®å¤ç使¶ç¨ |
| | | // âç¡®å®âæ¥å
³éå¯¹è¯æ¡ç代ç |
| | | // TODO: 卿¤æ¾ç½®å¤ç使¶ç¨ |
| | | // âç¡®å®âæ¥å
³éå¯¹è¯æ¡ç代ç |
| | | } |
| | | else if (nResponse == IDCANCEL) |
| | | { |
| | | // TODO: 卿¤æ¾ç½®å¤ç使¶ç¨ |
| | | // âåæ¶âæ¥å
³éå¯¹è¯æ¡ç代ç |
| | | // TODO: 卿¤æ¾ç½®å¤ç使¶ç¨ |
| | | // âåæ¶âæ¥å
³éå¯¹è¯æ¡ç代ç |
| | | } |
| | | else if (nResponse == -1) |
| | | { |
| | | TRACE(traceAppMsg, 0, "è¦å: å¯¹è¯æ¡å建失败ï¼åºç¨ç¨åºå°æå¤ç»æ¢ã\n"); |
| | | TRACE(traceAppMsg, 0, "è¦å: 妿æ¨å¨å¯¹è¯æ¡ä¸ä½¿ç¨ MFC æ§ä»¶ï¼åæ æ³ #define _AFX_NO_MFC_CONTROLS_IN_DIALOGSã\n"); |
| | | TRACE(traceAppMsg, 0, "è¦å: å¯¹è¯æ¡å建失败ï¼åºç¨ç¨åºå°æå¤ç»æ¢ã\n"); |
| | | TRACE(traceAppMsg, 0, "è¦å: 妿æ¨å¨å¯¹è¯æ¡ä¸ä½¿ç¨ MFC æ§ä»¶ï¼åæ æ³ #define _AFX_NO_MFC_CONTROLS_IN_DIALOGSã\n"); |
| | | } |
| | | |
| | | // å é¤ä¸é¢å建ç shell 管çå¨ã |
| | | // å é¤ä¸é¢å建ç shell 管çå¨ã |
| | | if (pShellManager != NULL) |
| | | { |
| | | delete pShellManager; |
| | | } |
| | | |
| | | // ç±äºå¯¹è¯æ¡å·²å
³éï¼æä»¥å°è¿å FALSE 以便éåºåºç¨ç¨åºï¼ |
| | | // è䏿¯å¯å¨åºç¨ç¨åºçæ¶æ¯æ³µã |
| | | // ç±äºå¯¹è¯æ¡å·²å
³éï¼æä»¥å°è¿å FALSE 以便éåºåºç¨ç¨åºï¼ |
| | | // è䏿¯å¯å¨åºç¨ç¨åºçæ¶æ¯æ³µã |
| | | return FALSE; |
| | | } |
| | | |
| | |
| | | m_model.term(); |
| | | HSMS_Term(); |
| | | RX_Term(); |
| | | UX_Shutdown(); |
| | | |
| | | // æ¸
ç GDI+ |
| | | // æ¸
ç GDI+ |
| | | TermGDIPlus(); |
| | | |
| | | // 鿝æ¥è¦è¡¨ |
| | | // 鿝æ¥è¦è¡¨ |
| | | AlarmManager::getInstance().termAlarmTable(); |
| | | |
| | | // 鿝æ¬è¿è®°å½ç®¡çåº |
| | | // 鿝æ¬è¿è®°å½ç®¡çåº |
| | | TransferManager::getInstance().termTransferTable(); |
| | | |
| | | // 鿝è¿è¡æ¥å¿ |
| | | // 鿝è¿è¡æ¥å¿ |
| | | SystemLogManager::getInstance().termSystemLogTable(); |
| | | |
| | | // éæ¯ç¨æ·è¡¨ |
| | | // éæ¯ç¨æ·è¡¨ |
| | | #if !defined(_DEBUG) |
| | | // æ¸
é¤ UserManager çæ æä½æ£æµ |
| | | // æ¸
é¤ UserManager çæ æä½æ£æµ |
| | | UserManager::getInstance().terminateIdleDetection(); |
| | | KillTimer(1); |
| | | #endif |
| | | |
| | | // 鿝é
æ¹è¡¨ |
| | | // 鿝é
æ¹è¡¨ |
| | | RecipeManager::getInstance().termRecipeTable(); |
| | | |
| | | return CWinApp::ExitInstance(); |
| | | } |
| | | |
| | | // åå§å GDI+ |
| | | // åå§å GDI+ |
| | | void CServoApp::InitGDIPlus() |
| | | { |
| | | // åå§å GDI+ å¾å½¢åº |
| | | // åå§å GDI+ å¾å½¢åº |
| | | GdiplusStartup(&g_diplusToken, &g_diplusStartupInput, NULL); |
| | | } |
| | | |
| | | // æ¸
ç GDI+ |
| | | // æ¸
ç GDI+ |
| | | void CServoApp::TermGDIPlus() |
| | | { |
| | | // æ¸
ç GDI+ å¾å½¢åº |
| | | // æ¸
ç GDI+ å¾å½¢åº |
| | | GdiplusShutdown(g_diplusToken); |
| | | } |
| | |
| | | <ClInclude Include="..\jsoncpp\include\json\value.h" /> |
| | | <ClInclude Include="..\jsoncpp\include\json\writer.h" /> |
| | | <ClInclude Include="..\jsoncpp\lib_json\json_batchallocator.h" /> |
| | | <ClInclude Include="AccordionWnd.h" /> |
| | | <ClInclude Include="AlarmPopupDlg.h" /> |
| | | <ClInclude Include="CBaseDlg.h" /> |
| | | <ClInclude Include="CCarrierSlotGrid.h" /> |
| | | <ClInclude Include="CCarrierSlotSelector.h" /> |
| | |
| | | <ClInclude Include="CControlJobManagerDlg.h" /> |
| | | <ClInclude Include="CCustomCheckBox.h" /> |
| | | <ClInclude Include="CCollectionEvent.h" /> |
| | | <ClInclude Include="CEventEditDlg.h" /> |
| | | <ClInclude Include="CEquipmentPage3.h" /> |
| | | <ClInclude Include="CExpandableListCtrl.h" /> |
| | | <ClInclude Include="CGlassPool.h" /> |
| | |
| | | <ClInclude Include="ClientListDlg.h" /> |
| | | <ClInclude Include="CMyStatusbar.h" /> |
| | | <ClInclude Include="CPageCollectionEvent.h" /> |
| | | <ClInclude Include="CPageCtrlState.h" /> |
| | | <ClInclude Include="CPageGlassList.h" /> |
| | | <ClInclude Include="CPageLinkSignal.h" /> |
| | | <ClInclude Include="CPageProdOverview.h" /> |
| | | <ClInclude Include="CPageReport.h" /> |
| | | <ClInclude Include="CPageVarialbles.h" /> |
| | | <ClInclude Include="CPageDataVarialbles.h" /> |
| | | <ClInclude Include="CPanelProduction.h" /> |
| | | <ClInclude Include="HmLabel.h" /> |
| | | <ClInclude Include="ProductionStats.h" /> |
| | | <ClInclude Include="CParam.h" /> |
| | | <ClInclude Include="CCjPage1.h" /> |
| | | <ClInclude Include="CProcessDataListDlg.h" /> |
| | | <ClInclude Include="CReport.h" /> |
| | | <ClInclude Include="CReportEditDlg.h" /> |
| | | <ClInclude Include="CRobotCmdContainerDlg.h" /> |
| | | <ClInclude Include="CRobotCmdTestDlg.h" /> |
| | | <ClInclude Include="CPagePortStatus.h" /> |
| | |
| | | <ClInclude Include="CRobotTaskDlg.h" /> |
| | | <ClInclude Include="CSVData.h" /> |
| | | <ClInclude Include="CServoUtilsTool.h" /> |
| | | <ClInclude Include="CUserManager2.h" /> |
| | | <ClInclude Include="CUserManager2Dlg.h" /> |
| | | <ClInclude Include="CUserEdit2Dlg.h" /> |
| | | <ClInclude Include="CUserXLogDlg.h" /> |
| | | <ClInclude Include="CVariable.h" /> |
| | | <ClInclude Include="CVariableEditDlg2.h" /> |
| | | <ClInclude Include="DeviceRecipeParamDlg.h" /> |
| | | <ClInclude Include="GlassJson.h" /> |
| | | <ClInclude Include="GlassLogDb.h" /> |
| | |
| | | <ClInclude Include="InputDialog.h" /> |
| | | <ClInclude Include="JobSlotGrid.h" /> |
| | | <ClInclude Include="LoginDlg.h" /> |
| | | <ClInclude Include="LoginDlg2.h" /> |
| | | <ClInclude Include="MsgDlg.h" /> |
| | | <ClInclude Include="PageRecipe.h" /> |
| | | <ClInclude Include="CDoubleGlass.h" /> |
| | |
| | | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> |
| | | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader> |
| | | </ClCompile> |
| | | <ClCompile Include="AccordionWnd.cpp" /> |
| | | <ClCompile Include="AlarmPopupDlg.cpp" /> |
| | | <ClCompile Include="CBaseDlg.cpp" /> |
| | | <ClCompile Include="CCarrierSlotGrid.cpp" /> |
| | | <ClCompile Include="CCarrierSlotSelector.cpp" /> |
| | |
| | | <ClCompile Include="CControlJobManagerDlg.cpp" /> |
| | | <ClCompile Include="CCustomCheckBox.cpp" /> |
| | | <ClCompile Include="CCollectionEvent.cpp" /> |
| | | <ClCompile Include="CEventEditDlg.cpp" /> |
| | | <ClCompile Include="CEquipmentPage3.cpp" /> |
| | | <ClCompile Include="CExpandableListCtrl.cpp" /> |
| | | <ClCompile Include="CGlassPool.cpp" /> |
| | |
| | | <ClCompile Include="ClientListDlg.cpp" /> |
| | | <ClCompile Include="CMyStatusbar.cpp" /> |
| | | <ClCompile Include="CPageCollectionEvent.cpp" /> |
| | | <ClCompile Include="CPageCtrlState.cpp" /> |
| | | <ClCompile Include="CPageGlassList.cpp" /> |
| | | <ClCompile Include="CPageLinkSignal.cpp" /> |
| | | <ClCompile Include="CPageProdOverview.cpp" /> |
| | | <ClCompile Include="CPageReport.cpp" /> |
| | | <ClCompile Include="CPageVarialbles.cpp" /> |
| | | <ClCompile Include="CPageDataVarialbles.cpp" /> |
| | | <ClCompile Include="ConfigurationProduction.cpp" /> |
| | | <ClCompile Include="CPanelProduction.cpp" /> |
| | | <ClCompile Include="HmLabel.cpp" /> |
| | | <ClCompile Include="ProductionStats.cpp" /> |
| | | <ClCompile Include="CParam.cpp" /> |
| | | <ClCompile Include="CCjPage1.cpp" /> |
| | | <ClCompile Include="CProcessDataListDlg.cpp" /> |
| | | <ClCompile Include="CReport.cpp" /> |
| | | <ClCompile Include="CReportEditDlg.cpp" /> |
| | | <ClCompile Include="CRobotCmdContainerDlg.cpp" /> |
| | | <ClCompile Include="CRobotCmdTestDlg.cpp" /> |
| | | <ClCompile Include="CPagePortStatus.cpp" /> |
| | |
| | | <ClCompile Include="CRobotTaskDlg.cpp" /> |
| | | <ClCompile Include="CSVData.cpp" /> |
| | | <ClCompile Include="CServoUtilsTool.cpp" /> |
| | | <ClCompile Include="CUserManager2.cpp" /> |
| | | <ClCompile Include="CUserManager2Dlg.cpp" /> |
| | | <ClCompile Include="CUserEdit2Dlg.cpp" /> |
| | | <ClCompile Include="CUserXLogDlg.cpp" /> |
| | | <ClCompile Include="CVariable.cpp" /> |
| | | <ClCompile Include="CVariableEditDlg2.cpp" /> |
| | | <ClCompile Include="DeviceRecipeParamDlg.cpp" /> |
| | | <ClCompile Include="GlassJson.cpp" /> |
| | | <ClCompile Include="GlassLogDb.cpp" /> |
| | |
| | | <ClCompile Include="InputDialog.cpp" /> |
| | | <ClCompile Include="JobSlotGrid.cpp" /> |
| | | <ClCompile Include="LoginDlg.cpp" /> |
| | | <ClCompile Include="LoginDlg2.cpp" /> |
| | | <ClCompile Include="MsgDlg.cpp" /> |
| | | <ClCompile Include="PageRecipe.cpp" /> |
| | | <ClCompile Include="CDoubleGlass.cpp" /> |
| | |
| | | <ClCompile Include="CReport.cpp" /> |
| | | <ClCompile Include="CVariable.cpp" /> |
| | | <ClCompile Include="CPageVarialbles.cpp" /> |
| | | <ClCompile Include="CPageDataVarialbles.cpp" /> |
| | | <ClCompile Include="CPageReport.cpp" /> |
| | | <ClCompile Include="CPageCollectionEvent.cpp" /> |
| | | <ClCompile Include="ProcessJob.cpp" /> |
| | |
| | | <ClCompile Include="..\DAQBridge\proto\ProtocolCodec.cpp"> |
| | | <Filter>DAQBridge</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="ClientListDlg.cpp" /> |
| | | <ClCompile Include="LoginDlg2.cpp" /> |
| | | <ClCompile Include="CUserManager2.cpp" /> |
| | | <ClCompile Include="CUserManager2Dlg.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" /> |
| | | <ClCompile Include="AccordionWnd.cpp" /> |
| | | <ClCompile Include="CPageProdOverview.cpp" /> |
| | | <ClCompile Include="HmLabel.cpp" /> |
| | | <ClCompile Include="CPageCtrlState.cpp" /> |
| | | <ClCompile Include="AlarmPopupDlg.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="CReport.h" /> |
| | | <ClInclude Include="CVariable.h" /> |
| | | <ClInclude Include="CPageVarialbles.h" /> |
| | | <ClInclude Include="CPageDataVarialbles.h" /> |
| | | <ClInclude Include="CPageReport.h" /> |
| | | <ClInclude Include="CPageCollectionEvent.h" /> |
| | | <ClInclude Include="ProcessJob.h" /> |
| | |
| | | <ClInclude Include="..\DAQBridge\DAQConfig.h"> |
| | | <Filter>DAQBridge</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="ClientListDlg.h" /> |
| | | <ClInclude Include="LoginDlg2.h" /> |
| | | <ClInclude Include="CUserManager2.h" /> |
| | | <ClInclude Include="CUserManager2Dlg.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" /> |
| | | <ClInclude Include="AccordionWnd.h" /> |
| | | <ClInclude Include="CPageProdOverview.h" /> |
| | | <ClInclude Include="HmLabel.h" /> |
| | | <ClInclude Include="CPageCtrlState.h" /> |
| | | <ClInclude Include="AlarmPopupDlg.h" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="Servo.rc" /> |
| | |
| | | <RemoteDebuggerCommand>\\DESKTOP-IODBVIQ\Servo\Debug\Servo.exe</RemoteDebuggerCommand> |
| | | <RemoteDebuggerWorkingDirectory>\\DESKTOP-IODBVIQ\Servo\Debug\</RemoteDebuggerWorkingDirectory> |
| | | <RemoteDebuggerServerName>DESKTOP-IODBVIQ</RemoteDebuggerServerName> |
| | | <DebuggerFlavor>WindowsRemoteDebugger</DebuggerFlavor> |
| | | <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> |
| | | </PropertyGroup> |
| | | </Project> |
| | |
| | | #include "CRobotCmdContainerDlg.h" |
| | | #include "CRobotCmdTestDlg.h" |
| | | #include "LoginDlg.h" |
| | | #include "LoginDlg2.h" |
| | | #include "ChangePasswordDlg.h" |
| | | #include "UserManagerDlg.h" |
| | | #include "SystemLogManagerDlg.h" |
| | |
| | | #include "InputDialog.h" |
| | | #include "ClientListDlg.h" |
| | | #include "CControlJobManagerDlg.h" |
| | | #include "AlarmManager.h" |
| | | #include "CUserManager2.h" |
| | | #include "CUserManager2Dlg.h" |
| | | #include "CUserXLogDlg.h" |
| | | |
| | | |
| | | #ifdef _DEBUG |
| | |
| | | #define TIMER_ID_UPDATE_RUMTIME 2 |
| | | |
| | | /* Test */ |
| | | #define TIMER_ID_TEST 3 |
| | | #define TIMER_ID_LOGIN 3 |
| | | |
| | | |
| | | // ç¨äºåºç¨ç¨åºâå
³äºâèå项ç CAboutDlg å¯¹è¯æ¡ |
| | |
| | | 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; |
| | |
| | | m_pTopToolbar = nullptr; |
| | | m_pMyStatusbar = nullptr; |
| | | m_pRobotTaskDlg = nullptr; |
| | | m_pTab = nullptr; |
| | | m_pAlarmPopupDlg = nullptr; |
| | | } |
| | | |
| | | void CServoDlg::DoDataExchange(CDataExchange* pDX) |
| | |
| | | ON_UPDATE_COMMAND_UI(ID_MENU_FILE_SECSTEST, &CServoDlg::OnUpdateMenuFileSecsTest) |
| | | ON_COMMAND(ID_MENU_PROJECT_VARIABLE_LIST, &CServoDlg::OnMenuProjectVarialbleList) |
| | | ON_UPDATE_COMMAND_UI(ID_MENU_PROJECT_VARIABLE_LIST, &CServoDlg::OnUpdateMenuProjectVarialbleList) |
| | | ON_COMMAND(ID_MENU_TEST_ALARM_ON, &CServoDlg::OnMenuTestAlarmOn) |
| | | ON_UPDATE_COMMAND_UI(ID_MENU_TEST_ALARM_ON, &CServoDlg::OnUpdateMenuTestAlarmOn) |
| | | ON_COMMAND(ID_MENU_TEST_ALARM_OFF, &CServoDlg::OnMenuTestAlarmOff) |
| | | ON_UPDATE_COMMAND_UI(ID_MENU_TEST_ALARM_OFF, &CServoDlg::OnUpdateMenuTestAlarmOff) |
| | | ON_COMMAND(ID_MENU_TEST_MESSAGE_SET, &CServoDlg::OnMenuTestMessageSet) |
| | | ON_UPDATE_COMMAND_UI(ID_MENU_TEST_MESSAGE_SET, &CServoDlg::OnUpdateMenuTestMessageSet) |
| | | ON_COMMAND(ID_MENU_TEST_MESSAGE_CLEAR, &CServoDlg::OnMenuTestMessageClear) |
| | | 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_TOOLS_CURVE_EMPTY, &CServoDlg::OnMenuToolsCurveEmptyMode) |
| | | ON_UPDATE_COMMAND_UI(ID_MENU_TOOLS_CURVE_EMPTY, &CServoDlg::OnUpdateMenuToolsCurveEmptyMode) |
| | | ON_COMMAND(ID_MENU_TOOLS_CURVE_PRODUCTION, &CServoDlg::OnMenuToolsCurveProductionMode) |
| | | ON_UPDATE_COMMAND_UI(ID_MENU_TOOLS_CURVE_PRODUCTION, &CServoDlg::OnUpdateMenuToolsCurveProductionMode) |
| | | 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() |
| | |
| | | ASSERT(m_pPanelAttributes); |
| | | m_pPanelEquipment->loadDataFromEquipment(pEquipment); |
| | | m_pPanelAttributes->ShowWindow(SW_HIDE); |
| | | if (!m_pPanelEquipment->IsWindowVisible()) { |
| | | if (!m_pPanelEquipment->IsWindowVisible() && m_nLeftPanelType == 1) { |
| | | m_pPanelEquipment->ShowWindow(SW_SHOW); |
| | | Resize(); |
| | | } |
| | |
| | | SetTimer(TIMER_ID_UPDATE_RUMTIME, 500, nullptr); |
| | | } |
| | | } |
| | | else if (RX_CODE_CONTROLJOB_CHANGED == code) { |
| | | auto* cj = theApp.m_model.getMaster().getControlJob(); |
| | | CString text; |
| | | if (cj != nullptr) { |
| | | std::string st = cj->getStateText(); |
| | | text.Format(_T("ControlJob: %s (%s)"), cj->id().c_str(), st.c_str()); |
| | | if (cj->state() == SERVO::CJState::Paused) { |
| | | text += _T(" [Paused]"); |
| | | } |
| | | } |
| | | else { |
| | | text = _T("ControlJob: None"); |
| | | } |
| | | if (m_pMyStatusbar != nullptr) { |
| | | m_pMyStatusbar->setJobText((LPTSTR)(LPCTSTR)text); |
| | | if (cj != nullptr && cj->state() == SERVO::CJState::Paused) { |
| | | m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_ALARM); |
| | | m_pMyStatusbar->setForegroundColor(RGB(0, 0, 0)); |
| | | } |
| | | } |
| | | } |
| | | else if (RX_CODE_EQ_ROBOT_TASK == code) { |
| | | int exCode; |
| | | if (pAny->getIntValue("exCode", exCode)) { |
| | |
| | | //dlg.DoModal(); |
| | | } |
| | | } |
| | | else if (RX_CODE_ALARM_SET == code || RX_CODE_ALARM_CLEAR == code) { |
| | | RefreshAlarmBadge(); |
| | | } |
| | | |
| | | if (RX_CODE_PASSIVE_STATUS_CHANGED == code) { |
| | | int state = 0; |
| | |
| | | |
| | | 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(); |
| | |
| | | } |
| | | } |
| | | |
| | | void CServoDlg::RefreshAlarmBadge() |
| | | { |
| | | if (m_pTopToolbar == nullptr) return; |
| | | auto activeAlarms = AlarmManager::getInstance().getActiveAlarms(); |
| | | |
| | | // ç»´æ¤æªè¯»å表ï¼å½åæ´»è·ä¸æªå¨å·²è¯»éåä¸çæ¥è¦ |
| | | std::unordered_set<int> activeIds; |
| | | m_unreadAlarms.clear(); |
| | | for (const auto& alarm : activeAlarms) { |
| | | activeIds.insert(alarm.nId); |
| | | if (m_ackAlarms.find(alarm.nId) == m_ackAlarms.end()) { |
| | | m_unreadAlarms.push_back(alarm); |
| | | } |
| | | } |
| | | // ç§»é¤å·²è¯»éåä¸å·²ä¸åæ´»è·çåè¦ |
| | | for (auto it = m_ackAlarms.begin(); it != m_ackAlarms.end(); ) { |
| | | if (activeIds.find(*it) == activeIds.end()) { |
| | | it = m_ackAlarms.erase(it); |
| | | } |
| | | else { |
| | | ++it; |
| | | } |
| | | } |
| | | |
| | | int count = static_cast<int>(m_unreadAlarms.size()); |
| | | |
| | | auto* pBtn = dynamic_cast<CBlButton*>(m_pTopToolbar->GetBtn(IDC_BUTTON_ALARM)); |
| | | if (pBtn != nullptr) { |
| | | if (count <= 0) { |
| | | pBtn->SetBadgeNumber(0); |
| | | pBtn->ShowDotBadge(FALSE, RGB(255, 0, 0)); |
| | | pBtn->StopFlash(); |
| | | } |
| | | else if (count <= 9) { |
| | | pBtn->ShowDotBadge(FALSE, RGB(255, 0, 0)); |
| | | pBtn->SetBadgeNumber(count); |
| | | if (!pBtn->IsFlash()) pBtn->Flash(600); |
| | | } |
| | | else { |
| | | pBtn->SetBadgeNumber(0); |
| | | pBtn->ShowDotBadge(TRUE, RGB(255, 0, 0)); |
| | | if (!pBtn->IsFlash()) pBtn->Flash(600); |
| | | } |
| | | pBtn->EnableWindow(TRUE); |
| | | } |
| | | } |
| | | |
| | | void CServoDlg::AckAlarm(int alarmId) |
| | | { |
| | | m_ackAlarms.insert(alarmId); |
| | | RefreshAlarmBadge(); |
| | | } |
| | | |
| | | void CServoDlg::RaiseTestAlarm() |
| | | { |
| | | theApp.m_model.raiseSoftAlarm(ALID_SOFTWARE_TEST_ALARM, "Test Alarm (Ctrl+Alt+T)"); |
| | | } |
| | | |
| | | void CServoDlg::ClearTestAlarm() |
| | | { |
| | | theApp.m_model.clearSoftAlarm(ALID_SOFTWARE_TEST_ALARM); |
| | | } |
| | | |
| | | void CServoDlg::MarkAlarmsRead() |
| | | { |
| | | auto* pBtn = dynamic_cast<CBlButton*>(m_pTopToolbar ? m_pTopToolbar->GetBtn(IDC_BUTTON_ALARM) : nullptr); |
| | | for (const auto& alarm : m_unreadAlarms) { |
| | | m_ackAlarms.insert(alarm.nId); |
| | | } |
| | | m_unreadAlarms.clear(); |
| | | if (pBtn != nullptr) { |
| | | pBtn->SetBadgeNumber(0); |
| | | pBtn->ShowDotBadge(FALSE, RGB(255, 0, 0)); |
| | | pBtn->StopFlash(); |
| | | } |
| | | } |
| | | |
| | | BOOL CServoDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | const ULONGLONG boot_ui_begin = GetTickCount64(); |
| | | CWaitCursor wait; // æ´ä¸ªåå§åææ¾ç¤ºçå¾
å
æ ï¼é¿å
ç¨æ·è¯¯ä»¥ä¸ºå¡æ» |
| | | |
| | | // å°âå
³äº...âèå项添å å°ç³»ç»èåä¸ã |
| | | |
| | |
| | | SetIcon(m_hIcon, FALSE); // 设置å°å¾æ |
| | | |
| | | |
| | | // æå¤§å/çªå£æ é¢/çæ¬å· |
| | | ShowWindow(SW_MAXIMIZE); |
| | | CString strTitle; |
| | | strTitle.Format(_T("Bond Master -- V%s(%d)"), theApp.m_strVersionName, theApp.m_nVersionNumber); |
| | | SetWindowText(strTitle); |
| | | |
| | | |
| | | // model init |
| | | const ULONGLONG boot_model_begin = GetTickCount64(); |
| | | theApp.m_model.init(); |
| | | SetTimer(TIMER_ID_TEST, 1000, nullptr); |
| | | LOGI("[BOOT][UI] m_model.init finished, cost=%llu ms (since OnInit start %llu ms)", |
| | | (unsigned long long)(GetTickCount64() - boot_model_begin), |
| | | (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | SetTimer(TIMER_ID_LOGIN, 1500, nullptr); |
| | | LOGI("[BOOT][UI] after model.init, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | |
| | | // èå |
| | | CMenu menu; |
| | | menu.LoadMenu(IDR_MENU_APP); |
| | | SetMenu(&menu); |
| | | LOGI("[BOOT][UI] menu loaded, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | |
| | | |
| | | // toolbar |
| | |
| | | ASSERT(hMenu); |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_SWITCH, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_JOBS)->EnableWindow(TRUE); |
| | | LOGI("[BOOT][UI] toolbar created, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | |
| | | |
| | | // Tab |
| | | const ULONGLONG boot_pages_begin = GetTickCount64(); |
| | | m_pPageGraph1 = new CPageGraph1(); |
| | | m_pPageGraph1->Create(IDD_PAGE_GRAPH1, this); |
| | | LOGI("[BOOT][UI] page Graph1 created, cost=%llu ms (elapsed=%llu ms)", |
| | | (unsigned long long)(GetTickCount64() - boot_pages_begin), |
| | | (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | m_pPageGraph2 = new CPageGraph2(); |
| | | m_pPageGraph2->Create(IDD_PAGE_GRAPH2, this); |
| | | LOGI("[BOOT][UI] page Graph2 created, cost=%llu ms (elapsed=%llu ms)", |
| | | (unsigned long long)(GetTickCount64() - boot_pages_begin), |
| | | (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | m_pPageGlassList = new CPageGlassList(); |
| | | m_pPageGlassList->Create(IDD_PAGE_GLASS_LIST, this); |
| | | LOGI("[BOOT][UI] page GlassList created, cost=%llu ms (elapsed=%llu ms)", |
| | | (unsigned long long)(GetTickCount64() - boot_pages_begin), |
| | | (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | m_pPageRecipe = new CPageRecipe(); |
| | | m_pPageRecipe->Create(IDD_PAGE_RECIPE, this); |
| | | LOGI("[BOOT][UI] page Recipe created, cost=%llu ms (elapsed=%llu ms)", |
| | | (unsigned long long)(GetTickCount64() - boot_pages_begin), |
| | | (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | m_pPageAlarm = new CPageAlarm(); |
| | | m_pPageAlarm->Create(IDD_DIALOG_ALARM, this); |
| | | LOGI("[BOOT][UI] page Alarm created, cost=%llu ms (elapsed=%llu ms)", |
| | | (unsigned long long)(GetTickCount64() - boot_pages_begin), |
| | | (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | m_pPageLog = new CPageLog(); |
| | | m_pPageLog->Create(IDD_DIALOG_LOG, this); |
| | | LOGI("[BOOT][UI] page Log created, cost=%llu ms (elapsed=%llu ms)", |
| | | (unsigned long long)(GetTickCount64() - boot_pages_begin), |
| | | (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | m_pPageTransferLog = new CPageTransferLog(); |
| | | m_pPageTransferLog->Create(IDD_PAGE_TRANSFER_LOG, this); |
| | | LOGI("[BOOT][UI] page TransferLog created, cost=%llu ms (elapsed=%llu ms)", |
| | | (unsigned long long)(GetTickCount64() - boot_pages_begin), |
| | | (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | |
| | | CHmTab* m_pTab = CHmTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd); |
| | | m_pTab = CHmTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd); |
| | | m_pTab->SetPaddingLeft(20); |
| | | m_pTab->SetItemMarginLeft(18); |
| | | m_pTab->AddItem("ç¶æå¾", FALSE); |
| | |
| | | m_pTab->SetCurSel(0); |
| | | m_pTab->SetBkgndColor(RGB(222, 222, 222)); |
| | | ShowChildPage(0); |
| | | LOGI("[BOOT][UI] pages/tabs created, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | |
| | | // 读å颿¿å®½ |
| | | 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(); |
| | | m_pPanelAttributes->Create(IDD_PANEL_ATTRIBUTES, this); |
| | | |
| | | LOGI("[BOOT][UI] panels created, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | |
| | | // statusbar |
| | | m_pMyStatusbar = new CMyStatusbar(); |
| | | m_pMyStatusbar->Create(IDD_STATUSBAR, this); |
| | | m_pMyStatusbar->ShowWindow(SW_SHOW); |
| | | m_pMyStatusbar->setJobText("ControlJob: None"); |
| | | LOGI("[BOOT][UI] statusbar created, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | |
| | | |
| | | |
| | |
| | | InitRxWindows(); |
| | | Resize(); |
| | | |
| | | // å è½½åå²ç¼åæç¤º |
| | | { |
| | | CWaitCursor wait; |
| | | if (m_pMyStatusbar != nullptr) { |
| | | m_pMyStatusbar->setRunTimeText(_T("æ£å¨å è½½åå²ç¼å...")); |
| | | m_pMyStatusbar->UpdateWindow(); |
| | | } |
| | | LOGI("[BOOT][UI] before master.init, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | |
| | | // ç¸å½äºå»¶æ¶è°ç¨masterçåå§å |
| | | const ULONGLONG boot_master_begin = GetTickCount64(); |
| | | theApp.m_model.m_master.init(); |
| | | LOGI("[BOOT][UI] m_master.init finished, cost=%llu ms (since OnInit start %llu ms)", |
| | | (unsigned long long)(GetTickCount64() - boot_master_begin), |
| | | (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | theApp.m_model.loadPortParams(); |
| | | } |
| | | |
| | | // è¿åç¶ææ è¿è¡æ¶é´æ¾ç¤ºï¼é¿å
ä¸ç´åçå¨âæ£å¨å è½½åå²ç¼å...âï¼ |
| | | if (m_pMyStatusbar != nullptr) { |
| | | CString strText; |
| | | GetRuntimeFormatText(strText, ""); |
| | | m_pMyStatusbar->setRunTimeText((LPTSTR)(LPCTSTR)strText); |
| | | } |
| | | |
| | | |
| | | // åå§åmaster以åéè¦æ§ä»¶ç»å®æ°æ® |
| | |
| | | |
| | | // æ´æ°ç»å½ç¶æ |
| | | UpdateLoginStatus(); |
| | | // åå§åæ¥è¦è§æ |
| | | RefreshAlarmBadge(); |
| | | //SystemLogManager::getInstance.log(SystemLogManager::LogType::Info, _T("BondEqå¯å¨...")); |
| | | //SystemLogManager::getInstance. |
| | | |
| | | |
| | | LOGI("[BOOT][UI] OnInitDialog finished, total cost=%llu ms", |
| | | (unsigned long long)(GetTickCount64() - boot_ui_begin)); |
| | | |
| | | return TRUE; // é¤éå°ç¦ç¹è®¾ç½®å°æ§ä»¶ï¼å¦åè¿å TRUE |
| | | } |
| | |
| | | pPage3->Create(IDD_PAGE_VARIABLE); |
| | | dlg.addPage(pPage3, "Variable"); |
| | | |
| | | CPageDataVarialbles* pPage4 = new CPageDataVarialbles(); |
| | | pPage4->Create(IDD_PAGE_VARIABLE); |
| | | dlg.addPage(pPage4, "DataVariable"); |
| | | |
| | | dlg.DoModal(); |
| | | } |
| | | |
| | | void CServoDlg::OnUpdateMenuProjectVarialbleList(CCmdUI* pCmdUI) |
| | | { |
| | | pCmdUI->Enable(TRUE); |
| | | } |
| | | |
| | | void CServoDlg::OnMenuTestAlarmOn() |
| | | { |
| | | RaiseTestAlarm(); |
| | | } |
| | | |
| | | void CServoDlg::OnUpdateMenuTestAlarmOn(CCmdUI* pCmdUI) |
| | | { |
| | | pCmdUI->Enable(TRUE); |
| | | } |
| | | |
| | | void CServoDlg::OnMenuTestAlarmOff() |
| | | { |
| | | ClearTestAlarm(); |
| | | } |
| | | |
| | | void CServoDlg::OnUpdateMenuTestAlarmOff(CCmdUI* pCmdUI) |
| | | { |
| | | pCmdUI->Enable(TRUE); |
| | | } |
| | |
| | | void CServoDlg::OnUpdateMenuToolsClientList(CCmdUI* pCmdUI) |
| | | { |
| | | pCmdUI->Enable(TRUE); |
| | | } |
| | | |
| | | void CServoDlg::OnMenuToolsCurveEmptyMode() |
| | | { |
| | | theApp.m_model.getMaster().setCurveMode(SERVO::CurveMode::EmptyChamber); |
| | | } |
| | | |
| | | void CServoDlg::OnUpdateMenuToolsCurveEmptyMode(CCmdUI* pCmdUI) |
| | | { |
| | | pCmdUI->Enable(TRUE); |
| | | pCmdUI->SetCheck(theApp.m_model.getMaster().getCurveMode() == SERVO::CurveMode::EmptyChamber); |
| | | } |
| | | |
| | | void CServoDlg::OnMenuToolsCurveProductionMode() |
| | | { |
| | | theApp.m_model.getMaster().setCurveMode(SERVO::CurveMode::Production); |
| | | } |
| | | |
| | | void CServoDlg::OnUpdateMenuToolsCurveProductionMode(CCmdUI* pCmdUI) |
| | | { |
| | | pCmdUI->Enable(TRUE); |
| | | pCmdUI->SetCheck(theApp.m_model.getMaster().getCurveMode() == SERVO::CurveMode::Production); |
| | | } |
| | | |
| | | 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() |
| | |
| | | m_pMyStatusbar = nullptr; |
| | | } |
| | | |
| | | if (m_pAlarmPopupDlg != nullptr) { |
| | | m_pAlarmPopupDlg->DestroyWindow(); |
| | | delete m_pAlarmPopupDlg; |
| | | m_pAlarmPopupDlg = nullptr; |
| | | } |
| | | |
| | | if (m_pRobotTaskDlg != nullptr) { |
| | | m_pRobotTaskDlg->DestroyWindow(); |
| | | delete m_pRobotTaskDlg; |
| | |
| | | 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() |
| | |
| | | m_pMyStatusbar->setRunTimeText((LPTSTR)(LPCTSTR)strText); |
| | | } |
| | | |
| | | else if(TIMER_ID_TEST == nIDEvent){ |
| | | static __int64 tttt = 0; |
| | | tttt++; |
| | | theApp.m_model.m_hsmsPassive.setVariableValue("CJobSpace", tttt % 10); |
| | | theApp.m_model.m_hsmsPassive.setVariableValue("PJobSpace", tttt % 5); |
| | | else if(TIMER_ID_LOGIN == nIDEvent){ |
| | | KillTimer(TIMER_ID_LOGIN); |
| | | if (!CUserManager2::getInstance().isLoggedIn()) { |
| | | CLoginDlg2 dlg; |
| | | if (dlg.DoModal() != IDOK) { |
| | | PostMessage(WM_CLOSE); |
| | | } |
| | | else { |
| | | bool bRet = CUserManager2::getInstance().login((LPTSTR)(LPCTSTR)dlg.m_strUsername, |
| | | (LPTSTR)(LPCTSTR)dlg.m_strPassword); |
| | | if (!bRet) { |
| | | AfxMessageBox("ç»å½å¤±è´¥ï¼è¯·æ£æ¥ç¨æ·åæå¯ç æ¯å¦æ£ç¡®ï¼"); |
| | | PostMessage(WM_CLOSE); |
| | | } |
| | | UpdateLoginStatus(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | 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; |
| | |
| | | void CServoDlg::UpdateLoginStatus() |
| | | { |
| | | HMENU hMenu = m_pTopToolbar->GetOperatorMenu(); |
| | | UserManager& userManager = UserManager::getInstance(); |
| | | if (userManager.isLoggedIn()) |
| | | { |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_LOGIN, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | ::EnableMenuItem(hMenu, ID_OPERATOR_CHANGE_PASSWORD, MF_BYCOMMAND | MF_ENABLED); |
| | | CUserManager2& userManager = CUserManager2::getInstance(); |
| | | if (userManager.isLoggedIn()) { |
| | | ::EnableMenuItem(hMenu, ID_OPERATOR_SYSTEM_LOG, MF_BYCOMMAND | MF_ENABLED); |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_SWITCH, MF_BYCOMMAND | MF_ENABLED); |
| | | ::EnableMenuItem(hMenu, ID_OPERATOR_LOGOUT, MF_BYCOMMAND | MF_ENABLED); |
| | | |
| | | if (userManager.getCurrentUserRole() == UserRole::SuperAdmin) { |
| | | if (userManager.IsAdminCurrent()) { |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_USER_MANAGER, MF_BYCOMMAND | MF_ENABLED); |
| | | } |
| | | else { |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_USER_MANAGER, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | } |
| | | |
| | | m_pTopToolbar->SetOperatorBtnText(userManager.getCurrentUser().c_str()); |
| | | m_pTopToolbar->SetOperatorBtnText(userManager.getCurrentUserName().c_str()); |
| | | } |
| | | else { |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_LOGIN, MF_BYCOMMAND | MF_ENABLED); |
| | | ::EnableMenuItem(hMenu, ID_OPERATOR_CHANGE_PASSWORD, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_USER_MANAGER, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | ::EnableMenuItem(hMenu, ID_OPERATOR_SYSTEM_LOG, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_SWITCH, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | ::EnableMenuItem(hMenu, ID_OPERATOR_LOGOUT, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | |
| | | m_pTopToolbar->SetOperatorBtnText(_T("æªç»å½")); |
| | | } |
| | | } |
| | |
| | | LRESULT CServoDlg::OnToolbarBtnClicked(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | int id = (int)lParam; |
| | | if (id == IDC_BUTTON_RUN || id == IDC_BUTTON_STOP) { |
| | | UserRole emRole = UserManager::getInstance().getCurrentUserRole(); |
| | | if (emRole != UserRole::SuperAdmin) { |
| | | AfxMessageBox(_T("å½åç¨æ·å¹¶é管çåï¼ï¼ï¼")); |
| | | return 1; |
| | | } |
| | | } |
| | | |
| | | if (id == IDC_BUTTON_RUN) { |
| | | int rc = UX_CanExecute(L"start"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return 0; |
| | | } |
| | | UX_RecordAction(L"start"); |
| | | |
| | | if (theApp.m_model.getMaster().getState() == SERVO::MASTERSTATE::MSERROR) { |
| | | AfxMessageBox("å½åææºå°åçé误ï¼ä¸è½å¯å¨ï¼è¯·ç¡®è®¤è§£å³é®é¢ååå°è¯éæ°å¯å¨ï¼"); |
| | | } |
| | |
| | | } |
| | | } |
| | | else if (id == IDC_BUTTON_STOP) { |
| | | int rc = UX_CanExecute(L"stop"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return 0; |
| | | } |
| | | UX_RecordAction(L"stop"); |
| | | |
| | | if (theApp.m_model.getMaster().stop() == 0) { |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE); |
| | | } |
| | |
| | | dlg.SetEFEM(pEFEM); |
| | | dlg.DoModal(); |
| | | } |
| | | else if (id == IDC_BUTTON_ALARM) { |
| | | if (m_pAlarmPopupDlg == nullptr) { |
| | | m_pAlarmPopupDlg = new CAlarmPopupDlg(); |
| | | m_pAlarmPopupDlg->Create(IDD_DIALOG_POPUP_ALARM, this); |
| | | m_pAlarmPopupDlg->CenterWindow(); |
| | | } |
| | | m_pAlarmPopupDlg->RefreshContent(); |
| | | m_pAlarmPopupDlg->ShowWindow(SW_SHOW); |
| | | MarkAlarmsRead(); |
| | | } |
| | | else if (id == IDC_BUTTON_SETTINGS) { |
| | | SERVO::CEquipment* pEq = theApp.m_model.m_master.getEquipment(EQ_ID_EFEM); |
| | | ((SERVO::CEFEM*)pEq)->printDebugRobotState(); |
| | |
| | | } |
| | | else if (id == IDC_BUTTON_OPERATOR) { |
| | | int menuId = (int)wParam; |
| | | if (menuId == 0) { |
| | | CUserManager2Dlg dlg; |
| | | dlg.DoModal(); |
| | | } |
| | | else if (menuId == 1) { |
| | | CUserXLogDlg dlg; |
| | | dlg.DoModal(); |
| | | } |
| | | else if (menuId == 2) { |
| | | CLoginDlg2 dlg; |
| | | if (dlg.DoModal() == IDOK) { |
| | | bool bRet = CUserManager2::getInstance().login((LPTSTR)(LPCTSTR)dlg.m_strUsername, |
| | | (LPTSTR)(LPCTSTR)dlg.m_strPassword); |
| | | if (!bRet) { |
| | | AfxMessageBox("ç»å½å¤±è´¥ï¼è¯·æ£æ¥ç¨æ·åæå¯ç æ¯å¦æ£ç¡®ï¼"); |
| | | } |
| | | UpdateLoginStatus(); |
| | | } |
| | | } |
| | | |
| | | /* |
| | | SystemLogManager& logManager = SystemLogManager::getInstance(); |
| | | UserManager& userManager = UserManager::getInstance(); |
| | | if (menuId == 0) { |
| | |
| | | } |
| | | |
| | | UpdateLoginStatus(); |
| | | */ |
| | | } |
| | | |
| | | return 0; |
| | |
| | | return 0; |
| | | } |
| | | |
| | | BOOL CServoDlg::PreTranslateMessage(MSG* pMsg) |
| | | { |
| | | return CDialogEx::PreTranslateMessage(pMsg); |
| | | } |
| | | |
| | | CString& CServoDlg::GetRuntimeFormatText(CString& strText, const char* pszSuffix) |
| | | { |
| | | ULONGLONG ullRunTime = (ULONGLONG)(theApp.m_model.getMaster().getRunTime() * 0.001); |
| | |
| | | // |
| | | |
| | | #pragma once |
| | | #include <vector> |
| | | #include <unordered_set> |
| | | #include "BlButton.h" |
| | | #include "PageLog.h" |
| | | #include "PageAlarm.h" |
| | |
| | | #include "CPanelMaster.h" |
| | | #include "CPanelEquipment.h" |
| | | #include "CPanelAttributes.h" |
| | | #include "CPanelProduction.h" |
| | | #include "CPageGraph1.h" |
| | | #include "CPageGraph2.h" |
| | | #include "HmTab.h" |
| | | #include "TopToolbar.h" |
| | | #include "CMyStatusbar.h" |
| | | #include "CRobotTaskDlg.h" |
| | | #include "CPageGlassList.h" |
| | | #include "CPageVarialbles.h" |
| | | #include "CPageDataVarialbles.h" |
| | | #include "AlarmPopupDlg.h" |
| | | #include "AlarmManager.h" |
| | | |
| | | |
| | | // CServoDlg å¯¹è¯æ¡ |
| | |
| | | |
| | | public: |
| | | void ShowTerminalText(const char* pszText, unsigned int duration = -1); |
| | | void AckAlarm(int alarmId); |
| | | |
| | | private: |
| | | void InitRxWindows(); |
| | | void RefreshAlarmBadge(); |
| | | void MarkAlarmsRead(); |
| | | void RaiseTestAlarm(); |
| | | void ClearTestAlarm(); |
| | | void Resize(); |
| | | void SetLeftPanelType(int type, bool resize = true); |
| | | void ShowChildPage(int index); |
| | | void UpdateLoginStatus(); |
| | | CString& GetRuntimeFormatText(CString& strText, const char* pszSuffix); |
| | |
| | | CPageAlarm* m_pPageAlarm; |
| | | CPageLog* m_pPageLog; |
| | | CPageTransferLog* m_pPageTransferLog; |
| | | CAlarmPopupDlg* m_pAlarmPopupDlg; |
| | | CHmTab* m_pTab; |
| | | std::vector<AlarmData> m_unreadAlarms; |
| | | std::unordered_set<int> m_ackAlarms; |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | |
| | | 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 OnUpdateMenuFileExit(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuProjectVarialbleList(); |
| | | afx_msg void OnUpdateMenuProjectVarialbleList(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuTestAlarmOn(); |
| | | afx_msg void OnUpdateMenuTestAlarmOn(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuTestAlarmOff(); |
| | | afx_msg void OnUpdateMenuTestAlarmOff(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuTestMessageSet(); |
| | | afx_msg void OnUpdateMenuTestMessageSet(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuTestMessageClear(); |
| | | afx_msg void OnUpdateMenuTestMessageClear(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuToolsClientList(); |
| | | afx_msg void OnUpdateMenuToolsClientList(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuToolsCurveEmptyMode(); |
| | | afx_msg void OnUpdateMenuToolsCurveEmptyMode(CCmdUI* pCmdUI); |
| | | afx_msg void OnMenuToolsCurveProductionMode(); |
| | | afx_msg void OnUpdateMenuToolsCurveProductionMode(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); |
| | | afx_msg void OnTabSelChanged(NMHDR* nmhdr, LRESULT* result); |
| | | LRESULT OnToolbarBtnClicked(WPARAM wParam, LPARAM lParam); |
| | | LRESULT OnStatusbarBtnClicked(WPARAM wParam, LPARAM lParam); |
| | | virtual BOOL PreTranslateMessage(MSG* pMsg); |
| | | }; |
| | |
| | | #include <ctime> |
| | | #include <iomanip> |
| | | #include <sstream> |
| | | #include <vector> |
| | | #include <cstdarg> |
| | | |
| | | CToolUnits::CToolUnits() |
| | | { |
| | |
| | | oss << std::put_time(&tm, "%Y%m%d%H%M%S"); // ä¾ï¼2025-09-15 08:23:07 |
| | | return oss.str(); |
| | | } |
| | | |
| | | std::wstring CToolUnits::AnsiToWString(const std::string& str) |
| | | { |
| | | if (str.empty()) return std::wstring(); |
| | | |
| | | int len = ::MultiByteToWideChar(CP_ACP, 0, |
| | | str.c_str(), -1, |
| | | nullptr, 0); |
| | | if (len <= 0) return std::wstring(); |
| | | |
| | | std::wstring ws; |
| | | ws.resize(len - 1); |
| | | |
| | | ::MultiByteToWideChar(CP_ACP, 0, |
| | | str.c_str(), -1, |
| | | &ws[0], len); |
| | | |
| | | return ws; |
| | | } |
| | | |
| | | std::string CToolUnits::WStringToAnsi(const std::wstring& wstr) |
| | | { |
| | | if (wstr.empty()) return std::string(); |
| | | |
| | | int len = ::WideCharToMultiByte(CP_ACP, 0, |
| | | wstr.c_str(), -1, |
| | | nullptr, 0, |
| | | nullptr, nullptr); |
| | | if (len <= 0) return std::string(); |
| | | |
| | | std::string str; |
| | | str.resize(len - 1); |
| | | |
| | | ::WideCharToMultiByte(CP_ACP, 0, |
| | | wstr.c_str(), -1, |
| | | &str[0], len, |
| | | nullptr, nullptr); |
| | | |
| | | return str; |
| | | } |
| | | std::string CToolUnits::formatString(const char* fmt, ...) |
| | | { |
| | | if (fmt == nullptr) return std::string(); |
| | | |
| | | char buf[512] = {0}; |
| | | va_list args; |
| | | va_start(args, fmt); |
| | | int n = _vsnprintf_s(buf, sizeof(buf), _TRUNCATE, fmt, args); |
| | | va_end(args); |
| | | |
| | | if (n >= 0 && n < (int)sizeof(buf)) { |
| | | return std::string(buf); |
| | | } |
| | | |
| | | // ????????????????? |
| | | std::vector<char> tmp((n > 0 ? n + 2 : 1024), 0); |
| | | va_start(args, fmt); |
| | | _vsnprintf_s(tmp.data(), tmp.size(), _TRUNCATE, fmt, args); |
| | | va_end(args); |
| | | return std::string(tmp.data()); |
| | | } |
| | |
| | | #include <chrono> |
| | | #include <optional> |
| | | #include <utility> |
| | | #include <vector> |
| | | #include <cstdarg> |
| | | |
| | | enum class QuickRange { Today, Last7Days, ThisMonth, ThisYear }; |
| | | using TP = std::chrono::system_clock::time_point; |
| | |
| | | const char* fmt = "%Y-%m-%d %H:%M:%S"); |
| | | static std::string TimePointToLocalStringMs(const std::optional<TP>& tp); |
| | | static std::string NowStrSec(); |
| | | static std::wstring AnsiToWString(const std::string& str); |
| | | static std::string WStringToAnsi(const std::wstring& wstr); |
| | | static std::string formatString(const char* fmt, ...); |
| | | }; |
| | | |
| | |
| | | #include "Common.h" |
| | | |
| | | |
| | | #define SHOW_BATCH 1 |
| | | #define SHOW_CT 1 |
| | | |
| | | // CTopToolbar å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CTopToolbar, CDialogEx) |
| | |
| | | m_btnOperator.SetMenu(hMenu); |
| | | |
| | | |
| | | CString strIniFile; |
| | | strIniFile.Format(_T("%s\\configuration.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | bool bEnableRunCT = GetPrivateProfileInt("APP", _T("EnableRunCT"), 0, strIniFile) != 0; |
| | | m_btnRunCt.ShowWindow(bEnableRunCT ? SW_SHOW : SW_HIDE); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | |
| | | x += BTN_WIDTH; |
| | | x += 2; |
| | | |
| | | #ifdef SHOW_BATCH |
| | | pItem = GetDlgItem(IDC_BUTTON_RUN_BATCH); |
| | | if (::IsWindowVisible(pItem->GetSafeHwnd())) { |
| | | pItem->MoveWindow(x, y, BTN_WIDTH, nBthHeight); |
| | | x += BTN_WIDTH; |
| | | x += 2; |
| | | #endif |
| | | } |
| | | |
| | | #ifdef SHOW_CT |
| | | pItem = GetDlgItem(IDC_BUTTON_RUN_CT); |
| | | if (::IsWindowVisible(pItem->GetSafeHwnd())) { |
| | | pItem->MoveWindow(x, y, BTN_WIDTH, nBthHeight); |
| | | x += BTN_WIDTH; |
| | | x += 2; |
| | | #endif |
| | | } |
| | | |
| | | pItem = GetDlgItem(IDC_BUTTON_STOP); |
| | | pItem->MoveWindow(x, y, BTN_WIDTH, nBthHeight); |
| | |
| | | |
| | | #include "..\RxWindows1.0\include\RxWindowsLib.h" |
| | | #include "..\HSMSSDK\Include\HSMSSDK.h" |
| | | |
| | | #include "..\UserXLibrary\UserXAPI.h" |
| | | |
| | | |
| | | #ifdef _UNICODE |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // UserX ç¨æ·ç®¡çåºï¼C æ¥å£ï¼/ UserX user management library (C API) |
| | | // è¦çåè½ / Features: users, roles, actions, auth, logsï¼åºå® SQLite3 æä¹
å / SQLite3 persistenceï¼ |
| | | |
| | | #pragma once |
| | | |
| | | #if defined(_WIN32) |
| | | # ifdef USERXLIBRARY_EXPORTS |
| | | # define UX_API extern "C" __declspec(dllexport) |
| | | # else |
| | | # define UX_API extern "C" __declspec(dllimport) |
| | | # endif |
| | | #else |
| | | # define UX_API extern "C" |
| | | #endif |
| | | |
| | | #include <wchar.h> |
| | | |
| | | |
| | | #ifdef _COMPILE_AS_LIB |
| | | #warning "compiling as lib!" |
| | | #else |
| | | #ifdef _DEBUG |
| | | #ifndef _WIN64 |
| | | #pragma comment(lib, "../USERXLibrary/lib/Win32/Debug/UserXLibrary.lib") |
| | | #else |
| | | #pragma comment(lib, "../USERXLibrary/lib/x64/Debug/UserXLibrary.lib") |
| | | #endif |
| | | #else |
| | | #ifndef _WIN64 |
| | | #pragma comment(lib, "../USERXLibrary/lib/Win32/Release/UserXLibrary.lib") |
| | | #else |
| | | #pragma comment(lib, "../USERXLibrary/lib/x64/Release/UserXLibrary.lib") |
| | | #endif |
| | | #endif |
| | | #endif // !BUILD_AS_LIB |
| | | |
| | | |
| | | // é¢å¤é误ç / Extra error code |
| | | #ifndef UX_ERR_BAD_PASSWORD |
| | | #define UX_ERR_BAD_PASSWORD -10 // å¯ç é误 / bad password |
| | | #endif |
| | | |
| | | // é误ç å®å®ä¹ / Error code macros |
| | | #define UX_OK 0 // æå / success |
| | | #define UX_ERR_INVALID_ARGS -1 // åæ°é误 / invalid arguments |
| | | #define UX_ERR_NOT_FOUND -2 // æªæ¾å° / not found |
| | | #define UX_ERR_EXISTS -3 // å·²åå¨ / already exists |
| | | #define UX_ERR_PERMISSION -4 // æéä¸è¶³ / permission denied |
| | | #define UX_ERR_NOT_LOGGED_IN -5 // æªç»å½ / not logged in |
| | | #define UX_ERR_BUFFER_TOO_SMALL -6 // ç¼å²åºä¸è¶³ / buffer too small |
| | | #define UX_ERR_DB -7 // I/O ææ°æ®åºé误 / I/O or database error |
| | | #define UX_ERR_NOT_DEFINED -8 // æªå®ä¹ï¼å¦å¨ä½ä¸åå¨ï¼/ not defined |
| | | #define UX_ERR_DB_NOT_EMPTY -9 // æ°æ®åºé空ï¼å·²åå§åï¼/ database not empty |
| | | |
| | | // è¿åç / Return codesï¼è¯¦è§ä¸æ¹å®ï¼ |
| | | // UX_OK, UX_ERR_INVALID_ARGS, UX_ERR_NOT_FOUND, UX_ERR_EXISTS, |
| | | // UX_ERR_PERMISSION, UX_ERR_NOT_LOGGED_IN, UX_ERR_BUFFER_TOO_SMALL, |
| | | // UX_ERR_DB, UX_ERR_NOT_DEFINED, UX_ERR_DB_NOT_EMPTY |
| | | |
| | | // åå§åï¼æå®æ°æ®ç®å½ï¼å
é¨å°æå¼/å建 SQLite æ°æ®åºæä»¶ UserX.db |
| | | // Init: provide data directory; opens/creates SQLite DB file UserX.db |
| | | UX_API int UX_Init(const wchar_t* storage_dir); |
| | | |
| | | // å¯éï¼è¦çæ°æ®åºè·¯å¾ï¼ä»
使ç¨ç¬¬ä¸ä¸ªåæ°ä½ä¸º .db æä»¶è·¯å¾ï¼å
¶ä»å¿½ç¥ï¼ |
| | | // Optional: override DB path (use first arg as .db path; others ignored) |
| | | UX_API int UX_SetStorage(const wchar_t* users_db_path, |
| | | const wchar_t* /*unused_logs*/, |
| | | const wchar_t* /*unused_roles*/, |
| | | const wchar_t* /*unused_actions*/); |
| | | |
| | | // é
ç½®è§è²ï¼name:level æè¡ï¼/ Configure roles from lines "name:level" |
| | | // ä»
å
许å¨âç©ºæ°æ®åºâï¼roles/users/actions/logs åè¡¨åæ æ°æ®ï¼æ¶è°ç¨ï¼å¦åè¿å -9ã |
| | | // Only allowed when DB is empty (roles/users/actions/logs all zero rows); otherwise returns -9. |
| | | // e.g. L"Admin:100\nEngineer:50\nOperator:10\n" |
| | | UX_API int UX_SetRoleDefinitions(const wchar_t* roles_text); |
| | | |
| | | // è·åè§è²å表ï¼name:level æè¡ï¼ï¼buffer 为空æä¸è¶³æ¶è¿åæéå¤§å° |
| | | // Get roles list as lines; returns required size if buffer is null/too small |
| | | UX_API int UX_GetRoles(wchar_t* buffer, int buffer_chars); |
| | | |
| | | // ç¨æ·ç®¡ç / User management |
| | | UX_API int UX_AddUser(const wchar_t* username, |
| | | const wchar_t* display_name, |
| | | const wchar_t* password, |
| | | const wchar_t* role_name); |
| | | |
| | | UX_API int UX_DeleteUser(const wchar_t* username); |
| | | |
| | | // æ´æ°ä»»æå段ï¼ä¼ nullptr è¡¨ç¤ºä¿æä¸åï¼/ Update subset; nullptr keeps field |
| | | UX_API int UX_UpdateUser(const wchar_t* username, |
| | | const wchar_t* new_display_name, |
| | | const wchar_t* new_password, |
| | | const wchar_t* new_role_name, |
| | | int enabled /* -1 keep, 0 disable, 1 enable */); |
| | | |
| | | UX_API int UX_EnableUser(const wchar_t* username, int enabled /*0/1*/); |
| | | UX_API int UX_ResetPassword(const wchar_t* username, const wchar_t* new_password); |
| | | UX_API int UX_RenameUser(const wchar_t* username, const wchar_t* new_display_name); |
| | | |
| | | // 管çåæéï¼å 餿æç¨æ· / Admin-only |
| | | UX_API int UX_DeleteAllUsers(); |
| | | |
| | | // è·åç¨æ·åè¡¨ï¼æ¯è¡ï¼username,display,level,enabledï¼/ Query users |
| | | UX_API int UX_GetUsers(wchar_t* buffer, int buffer_chars); |
| | | |
| | | // è®¤è¯ / Authentication |
| | | UX_API int UX_Login(const wchar_t* username, const wchar_t* password); |
| | | UX_API void UX_Logout(); |
| | | UX_API int UX_IsLoggedIn(); |
| | | UX_API void UX_Shutdown(); // éæ¾èµæº / shutdown and free resources |
| | | UX_API int UX_GetCurrentUser(wchar_t* buffer, int buffer_chars); |
| | | |
| | | // å¨ä½ä¸æé / Actions & permissions |
| | | // å®ä¹/è¦çå¨ä½ï¼åç§°ãæè¿°ãæä½è§è²ï¼/ Define/overwrite action |
| | | UX_API int UX_DefineAction(const wchar_t* action_name, |
| | | const wchar_t* description, |
| | | const wchar_t* min_role_name); |
| | | |
| | | // 坿§è¡è¿å1ï¼ä¸å¯æ§è¡è¿å0ï¼è´æ°ä¸ºé误 / 1 allowed, 0 denied |
| | | UX_API int UX_CanExecute(const wchar_t* action_name); |
| | | |
| | | // è®°å½å¨ä½å°æ¥å¿ï¼æ¶é´ãç¨æ·ãå¨ä½ãæè¿°ï¼/ Record action to logs |
| | | UX_API int UX_RecordAction(const wchar_t* action_name); |
| | | |
| | | // è·åå¨ä½åè¡¨ï¼æ¯è¡ï¼name,desc,minlevelï¼/ Get actions list |
| | | UX_API int UX_GetActions(wchar_t* buffer, int buffer_chars); |
| | | |
| | | // è®°å½å°è¯ï¼å
许/æç»ï¼/ record an attempt with allowed flag (1 allowed, 0 denied) |
| | | UX_API int UX_RecordAttempt(const wchar_t* action_name, int allowed /*1/0*/); |
| | | |
| | | // æ¥è¯¢æè¿ N æ¡æ¥å¿ï¼æ¯è¡ï¼ISO8601æ¶é´,ç¨æ·å,å¨ä½,æè¿°ï¼/ Query logs |
| | | UX_API int UX_QueryLogs(int last_n, wchar_t* buffer, int buffer_chars); |
| | | |
| | | // æ ¹æ®é误ç è¿åæåæè¿°ï¼ä¸æ/Englishï¼ |
| | | // Return a human-readable message for an error code |
| | | UX_API const wchar_t* UX_ErrorMessage(int code); |
| | |
| | | CEID,CE Name,Descriptions,Attached RPTID |
| | | 300,AccessMode_To_Manual,,(300) |
| | | 301,AccessMode_To_Auto,,(301) |
| | | 600,ControlStateChanged,,(600) |
| | | 700,ProcessStateChanged,,(700) |
| | | 10018,ProcessDataReport,,(33) |
| | | 10015,SubEqpStart,,(10015) |
| | | 10016,SubEqpEnd,,(10016) |
| | | 10017,SubEqpStateChange,,(10017) |
| | | 10000,RecipeChanged,,(10000) |
| | | 10030,CarrierArrived,,(10300) |
| | | 10031,CarrierRemoved,,(10300) |
| | | 10032,LoadPortNotAssoc,,(50014) |
| | | 10040,ReadyToLoad,,(10300) |
| | | 10041,ReadyToUnLoad,,(10300) |
| | | 10051,CarrierIDWaitingForHost,,(10051) |
| | | 10052,CarrierIDVerificationOK,,(10052) |
| | | 10053,CarrierIDVerificationNG,,(10052) |
| | | 10061,SlotMapWaitingForHost,,(10061) |
| | | 10061,CheckSlotMap,,(10061) |
| | | 10062,SlotMapVerificationOK,,(10062) |
| | | 10063,SlotMapVerificationNG,,(10062) |
| | | 10064,SlotMapMismatch,Slot map mismatch between scan and download,(10062) |
| | | 10071,GlassIDReadWaitingForHost,,(10071) |
| | | 10072,GlassIDReadVerificationOK,,(10072) |
| | | 10073,GlassIDReadVerificationNG,,(10072) |
| | |
| | | 50008,Port_Unload_Ready,,(50008) |
| | | 50009,Port_Load_Ready,,(50009) |
| | | 50010,Port_Blocked,,(50010) |
| | | |
| | | 50011,OCR_PanelID_Read_OK,OCR read OK and match,(50012) |
| | | 50015,OCR_PanelID_Read_NG,OCR read fail (key-in match),(50012) |
| | | 50016,OCR_PanelID_Read_Mismatch,OCR read OK but mismatch,(50012) |
| | | 50017,OCR_PanelID_Read_NG_Mismatch,OCR read fail and key-in mismatch,(50012) |
| | | 50012,Port_Ready_To_Release,,(50013) |
| | | 50020,PortStateChange,,(50020) |
| | | 50021,GlassReceivedJob,Glass received into equipment slot,(50021) |
| | | 50022,GlassSentOutJob,Glass sent out from equipment slot,(50022) |
| | | 60000,BonderSVData,,(60000) |
| | | 61000,BonderProcessData,,(61000) |
| | | 62000,VacuumBakeSVData,,(62000) |
| | | 63000,VacuumBakeProcessData,,(63000) |
| | | 64000,BakeCoolingSVData,,(64000) |
| | | 65000,BakeCoolingProcessData,,(65000) |
| | | 66000,MeasurementSVData,,(66000) |
| | | 67000,MeasurementProcessData,,(67000) |
| | | 12000,UnitStart,,(12000) |
| | | 12001,UnitStateChange,,(12001) |
| | | 12002,UnitEnd,,(12002) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | DVID,DV Name,DV Format,DV Remark |
| | | 6000,Bonder_SV_ProcessStep,A20,Bonder SV: å·¥èºè¿è¡æ¥éª¤ |
| | | 6001,Bonder_SV_BladderPressure,A20,Bonder SV: æ°åååå½å |
| | | 6002,Bonder_SV_UpperChamberPressure,A20,Bonder SV: ä¸è
ååå计 |
| | | 6003,Bonder_SV_PipeVacuumGauge,A20,Bonder SV: 管éç空表 |
| | | 6004,Bonder_SV_ChamberVacuumGauge,A20,Bonder SV: è
ä½ç空表 |
| | | 6005,Bonder_SV_UpperTemp1,A20,Bonder SV: ä¸è
温度1 |
| | | 6006,Bonder_SV_UpperTemp2,A20,Bonder SV: ä¸è
温度2 |
| | | 6007,Bonder_SV_UpperTemp3,A20,Bonder SV: ä¸è
温度3 |
| | | 6008,Bonder_SV_UpperTemp4,A20,Bonder SV: ä¸è
温度4 |
| | | 6009,Bonder_SV_UpperTemp5,A20,Bonder SV: ä¸è
温度5 |
| | | 6010,Bonder_SV_UpperTemp6,A20,Bonder SV: ä¸è
温度6 |
| | | 6011,Bonder_SV_LowerTemp1,A20,Bonder SV: ä¸è
温度1 |
| | | 6012,Bonder_SV_LowerTemp2,A20,Bonder SV: ä¸è
温度2 |
| | | 6013,Bonder_SV_LowerTemp3,A20,Bonder SV: ä¸è
温度3 |
| | | 6014,Bonder_SV_LowerTemp4,A20,Bonder SV: ä¸è
温度4 |
| | | 6015,Bonder_SV_LowerTemp5,A20,Bonder SV: ä¸è
温度5 |
| | | 6016,Bonder_SV_LowerTemp6,A20,Bonder SV: ä¸è
温度6 |
| | | 6017,Bonder_SV_HeatingRemaining,A20,Bonder SV: å çå©ä½æ¶é´ |
| | | 6018,Bonder_SV_PressingRemaining,A20,Bonder SV: ååå©ä½æ¶é´ |
| | | 6100,Bonder_PD_AlignDelay,A20,Bonder PD: 对ä½å»¶æ¶ |
| | | 6101,Bonder_PD_DwellTime,A20,Bonder PD: ä¿åæ¶é´ |
| | | 6102,Bonder_PD_BreakVacuumDelay,A20,Bonder PD: ç ´çç©ºå»¶æ¶ |
| | | 6103,Bonder_PD_TurboPumpStartDelay,A20,Bonder PD: ååæ³µå¯å¨å»¶æ¶ |
| | | 6104,Bonder_PD_AttachVacuumDelay,A20,Bonder PD: æ½çç©ºå»¶æ¶ |
| | | 6105,Bonder_PD_HeatingWaitDelay,A20,Bonder PD: çå¾
å çå»¶æ¶ |
| | | 6106,Bonder_PD_BladderPressureSet,A20,Bonder PD: æ°åååè®¾å® |
| | | 6107,Bonder_PD_BladderPressurizeRate,A20,Bonder PD: æ°åå åéç |
| | | 6108,Bonder_PD_BladderDepressurizeRate,A20,Bonder PD: æ°åæ³åéç |
| | | 6109,Bonder_PD_AttachPressureLimit,A20,Bonder PD: è´´åååä¸é |
| | | 6110,Bonder_PD_UpperZTorqueSpeed,A20,Bonder PD: ä¸è
Zé¢è´´åé度 |
| | | 6111,Bonder_PD_UpperTempSet,A20,Bonder PD: ä¸è
æ¸©åº¦è®¾å® |
| | | 6112,Bonder_PD_LowerTempSet,A20,Bonder PD: ä¸è
æ¸©åº¦è®¾å® |
| | | 6113,Bonder_PD_PreAttachSpeed,A20,Bonder PD: é¢è´´åé度 |
| | | 6114,Bonder_PD_AttachSpeed,A20,Bonder PD: è´´åé度 |
| | | 6115,Bonder_PD_UpperHeatDistance,A20,Bonder PD: ä¸è
å çè·ç¦» |
| | | 6116,Bonder_PD_AttachPressIn,A20,Bonder PD: è´´ååå
¥å |
| | | 6117,Bonder_PD_UpperBreakVacuumDist,A20,Bonder PD: ä¸è
ç ´ç空è·ç¦» |
| | | 6118,Bonder_PD_LowerPinBreakVacuumDist,A20,Bonder PD: ä¸é¡¶éç ´ç空è·ç¦» |
| | | 6119,Bonder_PD_LowerPinHeatDistance,A20,Bonder PD: ä¸é¡¶éå çè·ç¦» |
| | | 6120,Bonder_PD_PumpGaugeSet,A20,Bonder PD: ç空泵çç©ºè®¾å® |
| | | 6121,Bonder_PD_TurboReachSet,A20,Bonder PD: ååæ³µå°è¾¾è®¾å® |
| | | 6200,VacuumBake_SV_A_ProcessStep,A20,VacuumBake SV A: å·¥èºè¿è¡æ¥éª¤ |
| | | 6201,VacuumBake_SV_A_ChamberVacuum,A20,VacuumBake SV A: è
ä½ç空 |
| | | 6202,VacuumBake_SV_A_Temp1,A20,VacuumBake SV A: 温度1 |
| | | 6203,VacuumBake_SV_A_Temp2,A20,VacuumBake SV A: 温度2 |
| | | 6204,VacuumBake_SV_A_Temp4,A20,VacuumBake SV A: 温度4 |
| | | 6205,VacuumBake_SV_A_Temp5,A20,VacuumBake SV A: 温度5 |
| | | 6206,VacuumBake_SV_A_Temp6,A20,VacuumBake SV A: 温度6 |
| | | 6207,VacuumBake_SV_A_Temp7,A20,VacuumBake SV A: 温度7 |
| | | 6208,VacuumBake_SV_A_BakeRemaining,A20,VacuumBake SV A: çç¤å©ä½æ¶é´ |
| | | 6209,VacuumBake_SV_B_ProcessStep,A20,VacuumBake SV B: å·¥èºè¿è¡æ¥éª¤ |
| | | 6210,VacuumBake_SV_B_ChamberVacuum,A20,VacuumBake SV B: è
ä½ç空 |
| | | 6211,VacuumBake_SV_B_Temp1,A20,VacuumBake SV B: 温度1 |
| | | 6212,VacuumBake_SV_B_Temp2,A20,VacuumBake SV B: 温度2 |
| | | 6213,VacuumBake_SV_B_Temp4,A20,VacuumBake SV B: 温度4 |
| | | 6214,VacuumBake_SV_B_Temp5,A20,VacuumBake SV B: 温度5 |
| | | 6215,VacuumBake_SV_B_Temp6,A20,VacuumBake SV B: 温度6 |
| | | 6216,VacuumBake_SV_B_Temp7,A20,VacuumBake SV B: 温度7 |
| | | 6217,VacuumBake_SV_B_BakeRemaining,A20,VacuumBake SV B: çç¤å©ä½æ¶é´ |
| | | 6300,VacuumBake_PD_ParamIndex,A20,VacuumBake PD: åæ°åºå· |
| | | 6301,VacuumBake_PD_HeatTime,A20,VacuumBake PD: å çæ¶é´ |
| | | 6302,VacuumBake_PD_BreakVacuumTime,A20,VacuumBake PD: ç ´ç空æ¶é´ |
| | | 6303,VacuumBake_PD_VacuumReach,A20,VacuumBake PD: ç空达å°å¼ |
| | | 6304,VacuumBake_PD_TempSet,A20,VacuumBake PD: ä¸»æ§æ¸©åº¦è®¾å® |
| | | 6400,BakeCooling_SV_A_BakeStep,A20,BakeCooling SV A: çç¤æ¥éª¤ |
| | | 6401,BakeCooling_SV_A_Temp1,A20,BakeCooling SV A: 温度1 |
| | | 6402,BakeCooling_SV_A_Temp2,A20,BakeCooling SV A: 温度2 |
| | | 6403,BakeCooling_SV_A_Temp4,A20,BakeCooling SV A: 温度4 |
| | | 6404,BakeCooling_SV_A_Temp5,A20,BakeCooling SV A: 温度5 |
| | | 6405,BakeCooling_SV_A_Temp6,A20,BakeCooling SV A: 温度6 |
| | | 6406,BakeCooling_SV_A_Temp7,A20,BakeCooling SV A: 温度7 |
| | | 6407,BakeCooling_SV_A_BakeRemaining,A20,BakeCooling SV A: çç¤å©ä½æ¶é´ |
| | | 6408,BakeCooling_SV_A_CoolStep,A20,BakeCooling SV A: å·å´æ¥éª¤ |
| | | 6409,BakeCooling_SV_A_CoolRemaining,A20,BakeCooling SV A: å·å´å©ä½æ¶é´ |
| | | 6410,BakeCooling_SV_B_BakeStep,A20,BakeCooling SV B: çç¤æ¥éª¤ |
| | | 6411,BakeCooling_SV_B_Temp1,A20,BakeCooling SV B: 温度1 |
| | | 6412,BakeCooling_SV_B_Temp2,A20,BakeCooling SV B: 温度2 |
| | | 6413,BakeCooling_SV_B_Temp4,A20,BakeCooling SV B: 温度4 |
| | | 6414,BakeCooling_SV_B_Temp5,A20,BakeCooling SV B: 温度5 |
| | | 6415,BakeCooling_SV_B_Temp6,A20,BakeCooling SV B: 温度6 |
| | | 6416,BakeCooling_SV_B_Temp7,A20,BakeCooling SV B: 温度7 |
| | | 6417,BakeCooling_SV_B_BakeRemaining,A20,BakeCooling SV B: çç¤å©ä½æ¶é´ |
| | | 6418,BakeCooling_SV_B_CoolStep,A20,BakeCooling SV B: å·å´æ¥éª¤ |
| | | 6419,BakeCooling_SV_B_CoolRemaining,A20,BakeCooling SV B: å·å´å©ä½æ¶é´ |
| | | 6500,BakeCooling_PD_ParamIndex,A20,BakeCooling PD: åæ°åºå· |
| | | 6501,BakeCooling_PD_TimeOrTemp1,A20,BakeCooling PD: æ¶é´/温度1 |
| | | 6502,BakeCooling_PD_TimeOrTemp2,A20,BakeCooling PD: æ¶é´/温度2 |
| | | 6503,BakeCooling_PD_Reserved,A20,BakeCooling PD: é¢ç |
| | | 6600,Measurement_SV_ProcessStep,A20,Measurement SV: å·¥èºè¿è¡æ¥éª¤ |
| | | 6601,Measurement_SV_AOIScore,A20,Measurement SV: AOIåæ° |
| | | 6700,Measurement_PD_ParamIndex,A20,Measurement PD: åæ°åºå· |
| | | 6701,Measurement_PD_Time,A20,Measurement PD: æ¶é´ |
| | | 6702,Measurement_PD_Value1,A20,Measurement PD: æµéå¼1 |
| | | 6703,Measurement_PD_Value2,A20,Measurement PD: æµéå¼2 |
| | | 10200,SlotMap,U1,SlotMap(Scan) |
| | | 10201,SlotMapScan,U1,SlotMap(Scan) |
| | | 10202,SlotMapDownload,U1,SlotMap(Download) |
| | |
| | | RPTID,(VID1,VID2,...) |
| | | RPTID,(VID1,VID2,...) |
| | | # Notes: |
| | | # - RPTIDs 60000-67000, 700, 10017, 20000 include SubEqpName(5018) and SubEqpSlot(5019). |
| | | # - RPTIDs 50008/50009/50010/50013/50014/50020 use PortId(5022). |
| | | # - OCR events (CEID 50011/50015/50016/50017) use RPTID 50012 with VCRPanelID(5014). |
| | | |
| | | 33,(5017) |
| | | 300,(1,300) |
| | | 301,(1,300) |
| | | 600,(500,600,601) |
| | | 700,(500,700,701) |
| | | 700,(500,5018,5019,700,701) |
| | | 10000,(200,201) |
| | | 10300,(1,10000) |
| | | 10051,(1,10000,10100,10101) |
| | | 10061,(1,10000,10100,10200) |
| | | 10062,(1,10000,10100,10201,10202) |
| | | 10071,(1,10000,10100,10203,20000) |
| | | 10072,(1,10000,10100,10203,20000,20001) |
| | | 10080,(1,10000,10100) |
| | | 20000,(1,10000,10203) |
| | | 10300,(1,10000,10001,10002,10003) |
| | | 10051,(1,10000,10001,10002,10003,10100,10101) |
| | | 10061,(1,10000,10001,10002,10003,10100,10200) |
| | | 10062,(1,10000,10001,10002,10003,10100,10201,10202) |
| | | 10071,(1,10000,10001,10002,10003,10100,10203,20000) |
| | | 10072,(1,10000,10001,10002,10003,10100,10203,20000,20001) |
| | | 10080,(1,10000,10001,10002,10003,10100) |
| | | 20000,(1,5018,5019,10000,10001,10002,10003,10203) |
| | | 30000,(1,30000,30001) |
| | | 31000,(1,31000,31001) |
| | | 40000,(1,10203,20000) |
| | |
| | | 50005,(5007) |
| | | 50006,(5008) |
| | | 50007,(5009) |
| | | 50008,(5010) |
| | | 50009,(5011) |
| | | 50010,(5012) |
| | | |
| | | 50008,(5022) |
| | | 50009,(5022) |
| | | 50010,(5022) |
| | | 50011,(5013) |
| | | 50012,(5014) |
| | | 50013,(5022) |
| | | 50014,(5022) |
| | | 50020,(500,5022,5021) |
| | | 50021,(5018,5019,5023) |
| | | 50022,(5018,5019,5023) |
| | | 60000,(500,5018,5019,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016,6017,6018) |
| | | 61000,(500,5018,5019,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116,6117,6118,6119,6120,6121) |
| | | 62000,(500,5018,5019,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,6211,6212,6213,6214,6215,6216,6217) |
| | | 63000,(500,5018,5019,6300,6301,6302,6303,6304) |
| | | 64000,(500,5018,5019,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6414,6415,6416,6417,6418,6419) |
| | | 65000,(500,5018,5019,6500,6501,6502,6503) |
| | | 66000,(500,5018,5019,6600,6601) |
| | | 67000,(500,5018,5019,6700,6701,6702,6703) |
| | | 10015,(5018,5019) |
| | | 10016,(5018,5019) |
| | | 10017,(500,5018,5019) |
| | | 12000,(500,5018,5019) |
| | | 12001,(500,5018,5019) |
| | | 12002,(500,5018,5019) |
| | | |
| | |
| | | SVID,SV Name,SV Format,SV Remark |
| | | 100,PortTransferState,U1,0=OutOfService\r\n1=TransferBlocked\r\n2=ReadyToLoad\r\n3=ReadyToUnload\r\n4=InService\r\n5=TransferReady |
| | | 300,AccessMode,U1,1=Manual\r\n2=Auto |
| | | 500,Clock,A50, |
| | | 600,CurrentControlState,U1,0:Offline:equipment\r\n1:Offline-Attempt\r\n2:Online\r\n3:Offline:host\r\n4:Online:Local\r\n5:Online:Remote |
| | | 601,PreviousControlState,U1, |
| | | 700,CurrentProcessState,U1,0:DOWN\r\n1:IDLE\r\n2.SETUP\r\n3.EXCUTING\r\n4.MAINTAIN\r\n5.ALARM |
| | | 701,PreviousProcessState,U1, |
| | | 800,EFEMPPExecName,A20, |
| | | 801,EQPPExecName,A20, |
| | | 2000,RbRAxisTorque,I2,æºå¨äººRè½´æç© |
| | | 2001,RbLAxisTorque,l2,æºå¨äººLè½´æç© |
| | | 2002,RbZAxisTorque,l2,æºå¨äººZè½´æç© |
| | | 2003,RbTHAxisTorque,l2,æºå¨äººTHè½´æç© |
| | | 2004,RbXAxisTorque,l2,æºå¨äººXè½´æç© |
| | | 2005,AxisX111,l2,X111ç¸æºåç§»æ ½çµæºæç© |
| | | 2006,AxisX112,l2,X112ç¸æºåç§»æ ½çµæºæç© |
| | | 2007,AxisU113,l2,U113产åæè½¬çµæºæç© |
| | | 2008,AxisX114,l2,X114产åå·¦æ´åçµæºæç© |
| | | 2009,AxisY121,l2,Y121产å峿´åçµæºæç© |
| | | 2010,AxisY122,l2,Y122产ååæ´åçµæºæç© |
| | | 2011,AxisY123,l2,Y123产ååéµåçµæºæç© |
| | | 2012,MainAir,U2,æ»è¿æ°ååå¼ |
| | | 2013,MainVacuum,l2,æ»ç空ååå¼ |
| | | 2014,RbMainVacuum,l2,æºå¨äººçç©ºå¼ |
| | | 2015,LPMainVacuum,l2,LPç空å¼#D265 |
| | | 2016,LPMainAir,U2,LPåç©ºå¼ |
| | | 2017,ALVacuum,l2,Alignerçç©ºå¼ |
| | | 2018,FFU1RPM,U2,FFU1转é |
| | | 2019,FFU2RPM,U2,FFU2转é |
| | | 2020,FFU3RPM,U2,FFU3转é |
| | | 2021,FFU4RPM,U2,FFU4转é |
| | | 2022,ESDValue,I2,éçµæ£æµå¼ |
| | | 2023,OCREnable,U2,"OCR使è½ï¼O:å¼å¯ 1ï¼å±è½" |
| | | 2024,CCDEnable,U2,"CCD使è½ï¼O:å¼å¯ 1ï¼å±è½" |
| | | 2025,FFUParameter,U2,FFU设å®å¼ |
| | | 5000,CarrierID,A20,å¡å£ID |
| | | 10000,CarrierID_P1,A50,Carrier ID for Port 1 |
| | | 10001,CarrierID_P2,A50,Carrier ID for Port 2 |
| | | 10002,CarrierID_P3,A50,Carrier ID for Port 3 |
| | | 10003,CarrierID_P4,A50,Carrier ID for Port 4 |
| | | 100,PortTransferState_P1,U1,1=LoadReady;2=Loaded;3=InUse;4=UnloadReady;5=Empty;6=Blocked |
| | | 101,PortTransferState_P2,U1,1=LoadReady;2=Loaded;3=InUse;4=UnloadReady;5=Empty;6=Blocked |
| | | 102,PortTransferState_P3,U1,1=LoadReady;2=Loaded;3=InUse;4=UnloadReady;5=Empty;6=Blocked |
| | | 103,PortTransferState_P4,U1,1=LoadReady;2=Loaded;3=InUse;4=UnloadReady;5=Empty;6=Blocked |
| | | 300,AccessMode_P1,U1,0=OutOfService;1=TransferBlocked;2=ReadyToLoad;3=ReadyToUnload;4=InService;5=TransferReady |
| | | 301,AccessMode_P2,U1,0=OutOfService;1=TransferBlocked;2=ReadyToLoad;3=ReadyToUnload;4=InService;5=TransferReady |
| | | 302,AccessMode_P3,U1,0=OutOfService;1=TransferBlocked;2=ReadyToLoad;3=ReadyToUnload;4=InService;5=TransferReady |
| | | 303,AccessMode_P4,U1,0=OutOfService;1=TransferBlocked;2=ReadyToLoad;3=ReadyToUnload;4=InService;5=TransferReady |
| | | 500,Clock,A50,Current timestamp string |
| | | 600,CurrentControlState,U1,0=OfflineEquipment;1=OfflineAttempt;2=Online;3=OfflineHost;4=OnlineLocal;5=OnlineRemote |
| | | 601,PreviousControlState,U1,Previous control state (same code set as CurrentControlState) |
| | | 700,CurrentProcessState,U1,0=Ready;1=Processing;2=Complete;3=Error |
| | | 701,PreviousProcessState,U1,Previous process state (0=Ready;1=Processing;2=Complete;3=Error) |
| | | 800,EFEMPPExecName,A20,Current PPExec name from EFEM |
| | | 801,EQPPExecName,A20,Current PPExec name from equipment |
| | | 8100,Bonder1CurrentRecipe,A50,Current recipe for Bonder1 |
| | | 8101,Bonder2CurrentRecipe,A50,Current recipe for Bonder2 |
| | | 8102,VacuumBakeCurrentRecipe,A50,Current recipe for VacuumBake |
| | | 8103,BakeCoolingCurrentRecipe,A50,Current recipe for BakeCooling |
| | | 8104,MeasurementCurrentRecipe,A50,Current recipe for Measurement |
| | | 8105,EFEMCurrentRecipe,A50,Current recipe for EFEM |
| | | 5001,CJobSpace,U1,CJ Space |
| | | 5002,PJobSpace,U1,PJ Space |
| | | 5003,PJQueued,L,PJ Queued |
| | | 5004,PJStartID,A20,PJStartID |
| | | 5005,PJEndID,A20,PJEndID |
| | | 5006,PanelStartID,A20,PanelStartID |
| | | 5007,PanelEndID,A20,PanelEndID |
| | | 5008,CJStartID,A20,CJStartID |
| | | 5009,CJEndID,A20,CJEndID |
| | | 5010,UnloadReadyPortId,U2,"Port ID" |
| | | 5011,LoadReadyPortId,U2,"Port ID" |
| | | 5012,BlockedPortId,U2,"Port ID" |
| | | 5003,PJQueued,L,PJ queued list (IDs) |
| | | 5004,PJStartID,A20,PJ start ID |
| | | 5005,PJEndID,A20,PJ end ID |
| | | 5006,PanelStartID,A20,Panel start ID |
| | | 5007,PanelEndID,A20,Panel end ID |
| | | 5008,CJStartID,A20,CJ start ID |
| | | 5009,CJEndID,A20,CJ end ID |
| | | 5014,VCRPanelID,A20,Panel ID from reader |
| | | 5017,ProcessDataReportText,A50,EV_PROCESS_DATA_REPORT payload (placeholder) |
| | | 5018,SubEqpName,A20,Sub equipment name (SubEqp/Unit/Process/SV/ProcessData events) |
| | | 5019,SubEqpSlot,U1,Slot number for SubEqp/Unit; 0 when not applicable |
| | | 5021,PortState,U1,Port transfer/state code for PortStateChange |
| | | 5022,PortId,U1,Unified port ID for all Port events |
| | | 5023,MaterialId,A50,Material/Glass ID for Received/SentOut events |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | [SimEap] |
| | | ; Enable/disable simulator (1=on, 0=off) |
| | | Enabled=1 |
| | | |
| | | ; Step interval in milliseconds |
| | | IntervalMs=2000 |
| | | |
| | | ; Run a single step once. Change Step value to trigger again. |
| | | ; 0 means do nothing. |
| | | Step=1 |