SourceCode/Bond/BoounionPLC/BoounionPLC.cpp
@@ -136,6 +136,11 @@ m_model.setWorkDir((LPTSTR)(LPCTSTR)m_strAppDir); // gdi+ Gdiplus::GdiplusStartupInput gdiplusStartupInput; Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL); CString strIniFile; strIniFile.Format(_T("%s\\BoounionPLCconfiguration.ini"), (LPTSTR)(LPCTSTR)m_strAppDir); int plcTimeout = GetPrivateProfileInt("PLC", "Timeout", 700, strIniFile); @@ -192,6 +197,9 @@ int CBoounionPLCApp::ExitInstance() { // gdi+ Gdiplus::GdiplusShutdown(m_gdiplusToken); m_model.term(); RX_Term(); MCL_Term(); SourceCode/Bond/BoounionPLC/BoounionPLC.h
@@ -28,6 +28,7 @@ CString m_strAppFile; int m_nVersionNumber; CString m_strVersionName; ULONG_PTR m_gdiplusToken; // 重写 public: SourceCode/Bond/BoounionPLC/BoounionPLCDlg.cpp
@@ -141,6 +141,9 @@ theApp.m_model.setCurrentPlc(pPlc); } } else if (RX_PLC_STATE_CHANGED == code) { } else if (code == RX_CODE_ALARM_ON) { CPLC* pPlc; if (pAny->getPtrValue("ptr", (void*&)pPlc) && pPlc == theApp.m_model.getCurrentPlc()) { SourceCode/Bond/BoounionPLC/Common.h
@@ -20,6 +20,7 @@ #define RX_CODE_TACT_TIME 1014 // 节拍时间 #define RX_CODE_DAY_SHIFT_CAPACTITY 1015 // 白班产量 #define RX_CODE_NIGHT_SHIFT_CAPACTITY 1016 // 夜班产量 #define RX_PLC_STATE_CHANGED 1017 /* PLC状态改变 */ /* 定制颜色 */ @@ -115,6 +116,12 @@ #define BTN_SOUND_ON_BKGND_HOVER RGB(150, 250, 150) #define BTN_SOUND_ON_BKGND_PRESS RGB(50, 150, 50) /* 树控件小圆点 */ #define TREE_BADGE_BACKGROUND RGB(34, 177, 76) #define TREE_BADGE_FOREGROUND RGB(222, 222, 222) #define TREE_BADGE2_BACKGROUND RGB(255, 127, 39) #define TREE_BADGE2_FOREGROUND RGB(222, 222, 222) /* 按钮id */ #define VIEW_TOOL_BTN_CLOSE 0x1016 SourceCode/Bond/BoounionPLC/Model.cpp
@@ -21,6 +21,7 @@ m_pObservableEmitter = nullptr; m_pObservable = nullptr; m_nTimerID = 0; m_pActivePlc = nullptr; } @@ -337,7 +338,7 @@ pPLC->setWorkDir((LPTSTR)(LPCTSTR)strPlcDir); PLCListener listener; listener.onStateChanged = [&](void* pFrom, int state) -> void { LOGD("PLC状态改变,%d", state); notifyPtr(RX_PLC_STATE_CHANGED, pFrom); }; listener.onMonitorData = [&](void* pFrom, int id) -> void { LOGD("PLConMonitorData,%d", id); @@ -388,19 +389,10 @@ void CModel::setCurrentPlc(CPLC* pPlc) { if (pPlc != nullptr) { m_strCurrPlc = pPlc->getName(); } else { m_strCurrPlc = ""; } m_pActivePlc = pPlc; } CPLC* CModel::getCurrentPlc() { auto item = m_mapPlc.find(m_strCurrPlc); if (item != m_mapPlc.end()) { return item->second; } return nullptr; return m_pActivePlc; } SourceCode/Bond/BoounionPLC/Model.h
@@ -46,7 +46,7 @@ IObservableEmitter* m_pObservableEmitter; CString m_strWorkDir; std::map<std::string, CPLC*> m_mapPlc; std::string m_strCurrPlc; CPLC* m_pActivePlc; private: int m_nTimerID; SourceCode/Bond/BoounionPLC/PagePlcList.cpp
@@ -8,6 +8,8 @@ #include "Common.h" #define ID_TIMER_INIT 1 // CPagePlcList 对话框 IMPLEMENT_DYNAMIC(CPagePlcList, CDialogEx) @@ -36,6 +38,7 @@ ON_WM_DESTROY() ON_WM_SIZE() ON_MESSAGE(ID_MSG_TREE_CLICK_ITEM, OnTreeClickItem) ON_WM_TIMER() END_MESSAGE_MAP() @@ -82,6 +85,18 @@ theApp.m_model.notifyPtr(RX_CODE_SELECT_PLC, pSelectedPlc); } } else if (RX_PLC_STATE_CHANGED == code) { CPLC* pPlc; if (pAny->getPtrValue("ptr", (void*&)pPlc)) { HTREEITEM hItem = FindItem(pPlc); if (hItem != nullptr && pPlc->isConnected()) { m_treeCtrl.ShowItemBadgeDotMode(hItem); } else { m_treeCtrl.HideItemBadge(hItem); } } } pAny->release(); }, [&]() -> void { @@ -113,7 +128,8 @@ m_treeCtrl.SetBkColor(PAGE_PLC_LIST_BACKGROUND); m_treeCtrl.SetItemHeight(50); ReadPLCList(); SetTimer(ID_TIMER_INIT, 200, nullptr); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE @@ -182,14 +198,28 @@ void CPagePlcList::ReadPLCList() { HTREEITEM hItemFirst = nullptr; std::map<std::string, CPLC*>& plcs = theApp.m_model.getPlcMap(); for (auto item : plcs) { HTREEITEM hItem = m_treeCtrl.InsertItem(item.second->getName().c_str(), nullptr, nullptr); m_treeCtrl.SetItemData(hItem, (DWORD_PTR)item.second); m_treeCtrl.SetItemBadge(hItem, TREE_BADGE_BACKGROUND, TREE_BADGE_FOREGROUND); if (item.second->isConnected()) { m_treeCtrl.ShowItemBadgeDotMode(hItem); } if (hItemFirst == nullptr) { hItemFirst = hItem; } } if (!plcs.empty()) { m_treeCtrl.ShowWindow(SW_SHOW); GetDlgItem(IDC_LABEL_NO_PLC)->ShowWindow(SW_HIDE); } if (hItemFirst != nullptr) { m_treeCtrl.SelectItem(hItemFirst); CPLC* pPlc = (CPLC*)m_treeCtrl.GetItemData(hItemFirst); theApp.m_model.notifyPtr(RX_CODE_SELECT_PLC, pPlc); } } @@ -215,3 +245,14 @@ return nullptr; } void CPagePlcList::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (ID_TIMER_INIT == nIDEvent) { KillTimer(ID_TIMER_INIT); ReadPLCList(); } CDialogEx::OnTimer(nIDEvent); } SourceCode/Bond/BoounionPLC/PagePlcList.h
@@ -43,4 +43,5 @@ afx_msg void OnSize(UINT nType, int cx, int cy); virtual BOOL PreTranslateMessage(MSG* pMsg); afx_msg LRESULT OnTreeClickItem(WPARAM wParam, LPARAM lParam); afx_msg void OnTimer(UINT_PTR nIDEvent); }; SourceCode/Bond/HSMSSDK/Include/ISECS2Item.h
@@ -26,12 +26,20 @@ virtual SITYPE getType() = 0; virtual const char* toString() = 0; virtual bool getString(char*& pszText) = 0; virtual bool getBinary(BYTE& bin) = 0; virtual bool getBool(bool& boolValue) = 0; virtual bool getU4(unsigned int& value) = 0; virtual int getSubItemSize() = 0; virtual ISECS2Item* getSubItem(int index) = 0; virtual bool getSubItemString(int index, char*& pszText) = 0; virtual bool getSubItemBinary(int index, BYTE& bin) = 0; virtual bool getSubItemBool(int index, bool& boolValue) = 0; virtual bool getSubItemU4(int index, unsigned int& value) = 0; virtual void reset() = 0; virtual ISECS2Item* addItem(const char* pszText, const char* pszNote) = 0; virtual ISECS2Item* addBinaryItem(const char* pszData, int nDataLen, const char* pszNote) = 0; virtual void setBinary(const char* pszData, int nLen, const char* pszNote) = 0; virtual ISECS2Item* addBinaryItem(BYTE bin, const char* pszNote) = 0; virtual ISECS2Item* addBoolItem(bool boolValue, const char* pszNote) = 0; virtual ISECS2Item* addU4Item(unsigned int value, const char* pszNote) = 0; virtual void setBinary(BYTE bin, const char* pszNote) = 0; virtual ISECS2Item* addItem() = 0; }; SourceCode/Bond/Servo/HsmsAction.h
@@ -4,7 +4,7 @@ #define ACTION_IDLE 0 #define ACTION_HELLO 1 /* S1F1 */ #define ACTION_ALARM_REPORT 2 /* S5F1 */ class CHsmsAction { SourceCode/Bond/Servo/HsmsPassive.cpp
@@ -4,10 +4,11 @@ #include "Model.h" #include "Common.h" #include <time.h> #include <iostream> #include <time.h> #include <stdlib.h> #include <string.h> char g_szAckOkData[] = { 0, 0, 0, 0 }; char g_szAckNgData[] = { 1, 0, 0, 0 }; unsigned __stdcall CimWorkThreadFunction(LPVOID lpParam) { @@ -65,6 +66,23 @@ m_nActionTimeout = max(3, nSecond); } void CHsmsPassive::setEquipmentModelType(const char* pszMode) { m_strEquipmentModelType = pszMode; if (m_strEquipmentModelType.length() > 20) { m_strEquipmentModelType = m_strEquipmentModelType.substr(0, 20); } } void CHsmsPassive::setSoftRev(const char* pszRev) { m_strSoftRev = pszRev; if (m_strSoftRev.length() > 20) { m_strSoftRev = m_strSoftRev.substr(0, 20); } } void CHsmsPassive::OnTimer(UINT nTimerid) { // 所有已发送的Action自加1 @@ -84,6 +102,7 @@ int CHsmsPassive::onRecvMsg(IMessage* pMessage) { LOGI("onRecvMsg:%s", pMessage->toString()); Lock(); CHsmsAction* pAction = nullptr; for (auto iter = m_listActionSent.begin(); iter != m_listActionSent.end(); iter++) { @@ -165,6 +184,12 @@ } else if (nStream == 2 && pHeader->function == 31) { replyDatetime(pMessage); } else if (nStream == 2 && pHeader->function == 37) { replyEanbleDisableEventReport(pMessage); } else if (nStream == 5 && pHeader->function == 3) { replyEanbleDisableAlarmReport(pMessage); } }; @@ -321,7 +346,7 @@ ASSERT(pMessage); ISECS2Item* pItem = pMessage->getBody(); pItem->addBinaryItem(g_szAckOkData, 1, "COMMACK"); pItem->addBinaryItem(BYTE(0), "COMMACK"); ISECS2Item* pList = pItem->addItem(); pList->addItem(m_strEquipmentModelType.c_str(), "MDLN"); pList->addItem(m_strSoftRev.c_str(), "SOFTREV"); @@ -333,10 +358,6 @@ } // S2F31 #include <iostream> #include <time.h> #include <stdlib.h> #include <string.h> int CHsmsPassive::replyDatetime(IMessage* pRecv) { if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { @@ -372,10 +393,128 @@ ASSERT(pMessage); ISECS2Item* pItem = pMessage->getBody(); pItem->setBinary(g_szAckOkData, 1, "TIACK"); pItem->setBinary(BYTE(0), "TIACK"); m_pPassive->sendMessage(pMessage); LOGI("<HSMS>[SECS Msg SEND]S2F32 (SysByte=%u)", pRecv->getHeader()->systemBytes); HSMS_Destroy1Message(pMessage); return 0; } // S2F37 int CHsmsPassive::replyEanbleDisableEventReport(IMessage* pRecv) { if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { return ER_NOTSELECT; } ISECS2Item* pBody = pRecv->getBody(); if (pBody == nullptr || pBody->getType() != SITYPE::A) ER_PARAM_ERROR; BOOL bCheckData = FALSE; bool bEnable; std::vector<unsigned int> ids; { ISECS2Item* pItemIds; ISECS2Item* pItem = pRecv->getBody(); if (pItem->getSubItemSize() < 2) goto MYREPLY; if (!pItem->getSubItemBool(0, bEnable)) goto MYREPLY; pItemIds = pItem->getSubItem(1); if (pItemIds == nullptr || pItemIds->getType() != SITYPE::L) goto MYREPLY; for (int i = 0; i < pItemIds->getSubItemSize(); i++) { unsigned int id; if (pItemIds->getSubItemU4(i, id)) { ids.push_back(id); } } bCheckData = TRUE; LOGI("EanbleDisableAlarm bEnable:%s", bEnable ? _T("YES") : _T("NO")); for (auto item : ids) { LOGI("ID:%u", item); } } MYREPLY: int s = 2; int f = 38; IMessage* pMessage = NULL; HSMS_Create1Message(pMessage, m_nSessionId, s, f, pRecv->getHeader()->systemBytes); ASSERT(pMessage); ISECS2Item* pItem = pMessage->getBody(); pItem->setBinary(BYTE(0), "ERACK"); m_pPassive->sendMessage(pMessage); LOGI("<HSMS>[SECS Msg SEND]S%dF%d (SysByte=%u)", s, f, pRecv->getHeader()->systemBytes); HSMS_Destroy1Message(pMessage); return 0; } // S5F3 int CHsmsPassive::replyEanbleDisableAlarmReport(IMessage* pRecv) { if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { return ER_NOTSELECT; } ISECS2Item* pBody = pRecv->getBody(); if (pBody == nullptr || pBody->getType() != SITYPE::A) ER_PARAM_ERROR; BOOL bCheckData = FALSE; BYTE ALED; unsigned int ALID; { ISECS2Item* pItem = pRecv->getBody(); if (pItem->getSubItemSize() < 2) goto MYREPLY; if (!pItem->getSubItemBinary(0, ALED)) goto MYREPLY; if (!pItem->getSubItemU4(1, ALID)) goto MYREPLY; bCheckData = TRUE; LOGI("EanbleDisableAlarmReport ALED:%d, ALID:%d", ALED, ALID); } MYREPLY: int s = 5; int f = 4; IMessage* pMessage = NULL; HSMS_Create1Message(pMessage, m_nSessionId, s, f, pRecv->getHeader()->systemBytes); ASSERT(pMessage); ISECS2Item* pItem = pMessage->getBody(); pItem->setBinary(BYTE(0), "ACKC5"); m_pPassive->sendMessage(pMessage); LOGI("<HSMS>[SECS Msg SEND]S%dF%d (SysByte=%u)", s, f, pRecv->getHeader()->systemBytes); HSMS_Destroy1Message(pMessage); return 0; } // S5F1 int CHsmsPassive::requestAlarmReport(int ALCD, int ALID, const char* ALTX) { if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { return ER_NOTSELECT; } Lock(); CHsmsAction* pAction = new CHsmsAction(ACTION_ALARM_REPORT, TRUE, m_nActionTimeout); m_listAction.push_back(pAction); IMessage* pMessage = NULL; HSMS_Create1Message(pMessage, m_nSessionId, 5 | REPLY, 1, ++m_nSystemByte); ASSERT(pMessage); ISECS2Item* pItem = pMessage->getBody(); pItem->addBinaryItem(BYTE(ALCD & 0xff), "ALCD"); pItem->addU4Item(ALID, "ALID"); pItem->addItem(ALTX, "ALTX"); pAction->setSendMessage(pMessage); SetEvent(m_hCimWorkEvent); Unlock(); return ER_NOERROR; } SourceCode/Bond/Servo/HsmsPassive.h
@@ -17,6 +17,12 @@ ~CHsmsPassive(); public: /* 设置机器型号 最大长度 20 bytes */ void setEquipmentModelType(const char* pszMode); /* 设置软件版本号 最大长度 20 bytes */ void setSoftRev(const char* pszRev); unsigned OnCimWork(); void OnTimer(UINT nTimerid); void setActionTimeout(int nSecond); @@ -24,12 +30,17 @@ int term(); public: /* request开头的函数为主动发送数据的函数 */ int requestAreYouThere(); int requestAlarmReport(int ALCD, int ALID, const char* ALTX); private: /* reply开头的函数为回复函数 */ int replyAreYouThere(unsigned int systemBytes); int replyEstablishCommunications(unsigned int systemBytes); int replyDatetime(IMessage* pRecv); int replyEanbleDisableEventReport(IMessage* pRecv); int replyEanbleDisableAlarmReport(IMessage* pRecv); private: inline void Lock() { EnterCriticalSection(&m_criticalSection); } SourceCode/Bond/Servo/Model.cpp
@@ -32,6 +32,11 @@ m_configuration.setFilepath((LPTSTR)(LPCTSTR)strIniFile); m_configuration.getUnitId(strUnitId); // 机器型号和软件版本号应从配置中读取,当前先固定值 CString strModeType = _T("Bond2860"); CString strSoftRev = _T("1.0.2"); // Log CString strLogDir; @@ -52,6 +57,8 @@ }); m_hsmsPassive.setEquipmentModelType((LPTSTR)(LPCTSTR)strModeType); m_hsmsPassive.setSoftRev((LPTSTR)(LPCTSTR)strSoftRev); m_hsmsPassive.init(this, "APP", 7000); SourceCode/Bond/Servo/SecsTestDlg.cpp
@@ -30,6 +30,8 @@ BEGIN_MESSAGE_MAP(CSecsTestDlg, CDialogEx) ON_BN_CLICKED(IDC_BUTTON_S1F13, &CSecsTestDlg::OnBnClickedButtonS1f13) ON_BN_CLICKED(IDC_BUTTON_S1F1, &CSecsTestDlg::OnBnClickedButtonS1f1) ON_BN_CLICKED(IDC_BUTTON_S5F1_A, &CSecsTestDlg::OnBnClickedButtonS5f1A) ON_BN_CLICKED(IDC_BUTTON_S5F1_B, &CSecsTestDlg::OnBnClickedButtonS5f1B) END_MESSAGE_MAP() @@ -44,3 +46,21 @@ { } void CSecsTestDlg::OnBnClickedButtonS5f1A() { int ALCD, ALID; ALCD = 0; ALID = 1001; theApp.m_model.m_hsmsPassive.requestAlarmReport(ALCD, ALID, "ABC EFG"); } void CSecsTestDlg::OnBnClickedButtonS5f1B() { int ALCD, ALID; ALCD = 1; ALID = 1001; theApp.m_model.m_hsmsPassive.requestAlarmReport(ALCD, ALID, "ABCEFG"); } SourceCode/Bond/Servo/SecsTestDlg.h
@@ -23,4 +23,6 @@ public: afx_msg void OnBnClickedButtonS1f13(); afx_msg void OnBnClickedButtonS1f1(); afx_msg void OnBnClickedButtonS5f1A(); afx_msg void OnBnClickedButtonS5f1B(); }; SourceCode/Bond/Servo/Servo.rcBinary files differ
SourceCode/Bond/Servo/resource.hBinary files differ