| | |
| | | #include "Log.h" |
| | | |
| | | |
| | | static unsigned int DATAID = 1; |
| | | |
| | | CHsmsActive::CHsmsActive() |
| | | { |
| | | m_listener = {}; |
| | |
| | | return hsmsCarrierActionRequest(DATAID, "CarrierRelease", pszCarrierId, PTN); |
| | | } |
| | | |
| | | 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"); |
| | | auto itemPjs = pMessage->getBody()->addItem(); |
| | | for (auto pj : pjs) { |
| | | auto itemPj = itemPjs->addItem(); |
| | | itemPj->addItem(pj->id().c_str(), "PRJOBID"); |
| | | itemPj->addBinaryItem(szMF, 1, "MF"); |
| | | auto itemCarriers = itemPj->addItem(); |
| | | for (auto c : pj->carriers()) { |
| | | auto itemCarrier = itemCarriers->addItem(); |
| | | itemCarrier->addItem(c.carrierId.c_str(), "CARRIERID"); |
| | | auto itemSlots = itemCarrier->addItem(); |
| | | for (auto s : c.slots) { |
| | | itemSlots->addU1Item(s, "SLOTID"); |
| | | } |
| | | } |
| | | |
| | | auto recipeItems = itemPj->addItem(); |
| | | recipeItems->addU1Item(1, "PRRECIPEMETHOD"); |
| | | recipeItems->addItem(pj->recipeSpec().c_str(), "RCPSPEC"); |
| | | recipeItems->addItem(); |
| | | |
| | | itemPj->addBoolItem(false, "PRPROCESSSTART"); |
| | | itemPj->addItem(); |
| | | } |
| | | |
| | | m_pActive->sendMessage(pMessage); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsActive::replyAck0(IMessage* pMessage) |
| | | { |
| | | return 0; |
| | |
| | | #include <map> |
| | | #include <set> |
| | | #include "CCollectionEvent.h" |
| | | #include "ProcessJob.h" |
| | | |
| | | |
| | | #define SVID_CJobSpace 5001 |
| | |
| | | const char* pszCarrierId, |
| | | unsigned char PTN); |
| | | |
| | | // S16F15 |
| | | int hsmsPRJobMultiCreate(std::vector<SERVO::CProcessJob*>& pjs); |
| | | |
| | | // éè¿çreply彿° |
| | | void replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // CPJsDlg.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "pch.h" |
| | | #include "EAPSimulator.h" |
| | | #include "CPJsDlg.h" |
| | | #include "afxdialogex.h" |
| | | |
| | | |
| | | // CPJsDlg å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CPJsDlg, CDialogEx) |
| | | |
| | | CPJsDlg::CPJsDlg(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_PJS, pParent) |
| | | { |
| | | |
| | | } |
| | | |
| | | CPJsDlg::~CPJsDlg() |
| | | { |
| | | for (auto item : m_pjs) { |
| | | delete item; |
| | | } |
| | | m_pjs.clear(); |
| | | } |
| | | |
| | | void CPJsDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CPJsDlg, CDialogEx) |
| | | ON_BN_CLICKED(IDC_BUTTON_ADD, &CPJsDlg::OnBnClickedButtonAdd) |
| | | ON_BN_CLICKED(IDC_BUTTON_DELETE, &CPJsDlg::OnBnClickedButtonDelete) |
| | | ON_BN_CLICKED(IDC_BUTTON_SEND, &CPJsDlg::OnBnClickedButtonSend) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CPJsDlg æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | void CPJsDlg::OnBnClickedButtonAdd() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | } |
| | | |
| | | void CPJsDlg::OnBnClickedButtonDelete() |
| | | { |
| | | CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1); |
| | | int nSel = pListCtrl->GetNextItem(-1, LVNI_SELECTED); |
| | | |
| | | if (nSel != -1) { |
| | | SERVO::CProcessJob* pj = (SERVO::CProcessJob*)pListCtrl->GetItemData(nSel); |
| | | for (auto iter = m_pjs.begin(); iter != m_pjs.end(); ++iter) { |
| | | if (*iter == pj) { |
| | | delete (*iter); |
| | | m_pjs.erase(iter); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | pListCtrl->DeleteItem(nSel); |
| | | } |
| | | |
| | | void CPJsDlg::OnBnClickedButtonSend() |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsPRJobMultiCreate(m_pjs); |
| | | } |
| | | |
| | | BOOL CPJsDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | |
| | | // æ¥è¡¨æ§ä»¶ |
| | | CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1); |
| | | DWORD dwStyle = pListCtrl->GetExtendedStyle(); |
| | | dwStyle |= LVS_EX_FULLROWSELECT; |
| | | dwStyle |= LVS_EX_GRIDLINES; |
| | | pListCtrl->SetExtendedStyle(dwStyle); |
| | | |
| | | HIMAGELIST imageList = ImageList_Create(24, 24, ILC_COLOR24, 1, 1); |
| | | ListView_SetImageList(pListCtrl->GetSafeHwnd(), imageList, LVSIL_SMALL); |
| | | pListCtrl->InsertColumn(0, _T(""), LVCFMT_RIGHT, 0); |
| | | pListCtrl->InsertColumn(1, _T("PJ ID"), LVCFMT_LEFT, 100); |
| | | pListCtrl->InsertColumn(2, _T("Carrier1 & Slots"), LVCFMT_LEFT, 180); |
| | | pListCtrl->InsertColumn(3, _T("Carrier2 & Slots"), LVCFMT_LEFT, 180); |
| | | pListCtrl->InsertColumn(4, _T("Carrier3 & Slots"), LVCFMT_LEFT, 180); |
| | | pListCtrl->InsertColumn(5, _T("Carrier4 & Slots"), LVCFMT_LEFT, 180); |
| | | pListCtrl->InsertColumn(6, _T("PPID"), LVCFMT_LEFT, 180); |
| | | |
| | | |
| | | |
| | | // å建ç¨äºæµè¯çPJ |
| | | { |
| | | SERVO::CProcessJob* pj = new SERVO::CProcessJob("PJ0001"); |
| | | std::vector<uint8_t> slots1{ 1, 2, 3 }; |
| | | pj->addCarrier("CID1001", slots1); |
| | | pj->setRecipe(SERVO::RecipeMethod::NoTuning, "P1001"); |
| | | m_pjs.push_back(pj); |
| | | } |
| | | { |
| | | SERVO::CProcessJob* pj = new SERVO::CProcessJob("PJ0002"); |
| | | std::vector<uint8_t> slots1{ 1, 3 }; |
| | | pj->addCarrier("CID1002", slots1); |
| | | std::vector<uint8_t> slots2{ 1}; |
| | | pj->addCarrier("CID1003", slots2); |
| | | pj->setRecipe(SERVO::RecipeMethod::NoTuning, "R002"); |
| | | m_pjs.push_back(pj); |
| | | } |
| | | { |
| | | SERVO::CProcessJob* pj = new SERVO::CProcessJob("PJ0003"); |
| | | std::vector<uint8_t> slots1{ 1, 2, 3, 5 }; |
| | | pj->addCarrier("CID1004", slots1); |
| | | pj->setRecipe(SERVO::RecipeMethod::NoTuning, "P1001"); |
| | | m_pjs.push_back(pj); |
| | | } |
| | | |
| | | // æ¾ç¤ºå°æ¥è¡¨ä¸ |
| | | for (auto item : m_pjs) { |
| | | AddPjToListCtrl(item); |
| | | } |
| | | |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | | |
| | | void CPJsDlg::AddPjToListCtrl(SERVO::CProcessJob* pj) |
| | | { |
| | | CListCtrl* pListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1); |
| | | pListCtrl->InsertItem(0, _T("")); |
| | | pListCtrl->SetItemData(0, (DWORD_PTR)pj); |
| | | pListCtrl->SetItemText(0, 1, pj->id().c_str()); |
| | | pListCtrl->SetItemText(0, 6, pj->recipeSpec().c_str()); |
| | | |
| | | auto carries = pj->carriers(); |
| | | for (int i = 0; i < min(4, carries.size()); i++) { |
| | | pListCtrl->SetItemText(0, 2 + i, GetFormatString(carries[i])); ; |
| | | } |
| | | } |
| | | |
| | | CString CPJsDlg::GetFormatString(SERVO::CarrierSlotInfo& csi) |
| | | { |
| | | CString strRet; |
| | | strRet.Append(csi.carrierId.c_str()); |
| | | strRet.Append("<"); |
| | | int size = min(8, csi.slots.size()); |
| | | for (int i = 0; i < size; i++) { |
| | | strRet.Append(std::to_string(csi.slots[i]).c_str()); |
| | | if (i != size - 1) { |
| | | strRet.Append(","); |
| | | } |
| | | } |
| | | strRet.Append(">"); |
| | | |
| | | return strRet; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "ProcessJob.h" |
| | | #include <vector> |
| | | |
| | | |
| | | // CPJsDlg å¯¹è¯æ¡ |
| | | |
| | | class CPJsDlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CPJsDlg) |
| | | |
| | | public: |
| | | CPJsDlg(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CPJsDlg(); |
| | | void AddPjToListCtrl(SERVO::CProcessJob* pj); |
| | | CString GetFormatString(SERVO::CarrierSlotInfo& csi); |
| | | |
| | | private: |
| | | std::vector<SERVO::CProcessJob*> m_pjs; |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_PJS }; |
| | | #endif |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | afx_msg void OnBnClickedButtonAdd(); |
| | | afx_msg void OnBnClickedButtonDelete(); |
| | | afx_msg void OnBnClickedButtonSend(); |
| | | virtual BOOL OnInitDialog(); |
| | | }; |
| | |
| | | <SDLCheck>true</SDLCheck> |
| | | <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| | | <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> |
| | | <LanguageStandard>stdcpp17</LanguageStandard> |
| | | </ClCompile> |
| | | <Link> |
| | | <SubSystem>Windows</SubSystem> |
| | |
| | | <ClInclude Include="CModel.h" /> |
| | | <ClInclude Include="Common.h" /> |
| | | <ClInclude Include="Context.h" /> |
| | | <ClInclude Include="CPJsDlg.h" /> |
| | | <ClInclude Include="CReport.h" /> |
| | | <ClInclude Include="CTerminalDisplayDlg.h" /> |
| | | <ClInclude Include="CVariable.h" /> |
| | |
| | | <ClInclude Include="Log.h" /> |
| | | <ClInclude Include="LogEdit.h" /> |
| | | <ClInclude Include="pch.h" /> |
| | | <ClInclude Include="ProcessJob.h" /> |
| | | <ClInclude Include="Resource.h" /> |
| | | <ClInclude Include="targetver.h" /> |
| | | </ItemGroup> |
| | |
| | | <ClCompile Include="CLinkReportDlg.cpp" /> |
| | | <ClCompile Include="CModel.cpp" /> |
| | | <ClCompile Include="Context.cpp" /> |
| | | <ClCompile Include="CPJsDlg.cpp" /> |
| | | <ClCompile Include="CReport.cpp" /> |
| | | <ClCompile Include="CTerminalDisplayDlg.cpp" /> |
| | | <ClCompile Include="CVariable.cpp" /> |
| | |
| | | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> |
| | | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> |
| | | </ClCompile> |
| | | <ClCompile Include="ProcessJob.cpp" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="EAPSimulator.rc" /> |
| | |
| | | <ClInclude Include="CLinkReportDetailDlg.h"> |
| | | <Filter>头æä»¶</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="CPJsDlg.h"> |
| | | <Filter>头æä»¶</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="ProcessJob.h"> |
| | | <Filter>头æä»¶</Filter> |
| | | </ClInclude> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClCompile Include="EAPSimulator.cpp"> |
| | |
| | | <ClCompile Include="CLinkReportDetailDlg.cpp"> |
| | | <Filter>æºæä»¶</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="CPJsDlg.cpp"> |
| | | <Filter>æºæä»¶</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="ProcessJob.cpp"> |
| | | <Filter>æºæä»¶</Filter> |
| | | </ClCompile> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="EAPSimulator.rc"> |
| | |
| | | #include "CEDEventReportDlg.h" |
| | | #include "CDefineReportsDlg.h" |
| | | #include "CLinkReportDlg.h" |
| | | #include "CPJsDlg.h" |
| | | |
| | | |
| | | #ifdef _DEBUG |
| | |
| | | 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) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | |
| | | 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); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonConnect() |
| | |
| | | { |
| | | theApp.m_model.m_pHsmsActive->hsmsCarrierRelease(DATAID++, "CSX 52078", 2); |
| | | } |
| | | |
| | | void CEAPSimulatorDlg::OnBnClickedButtonCreatePj() |
| | | { |
| | | CPJsDlg dlg; |
| | | dlg.DoModal(); |
| | | } |
| | |
| | | afx_msg void OnBnClickedButtonCarrierRelease(); |
| | | afx_msg void OnBnClickedButtonQueryCjSpace(); |
| | | afx_msg void OnBnClickedButtonQueryPjSpace(); |
| | | afx_msg void OnBnClickedButtonCreatePj(); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "pch.h" |
| | | #include "ProcessJob.h" |
| | | #include <cctype> |
| | | |
| | | namespace SERVO { |
| | | static inline std::string trimCopy(std::string s) { |
| | | auto notspace = [](int ch) { return !std::isspace(ch); }; |
| | | s.erase(s.begin(), std::find_if(s.begin(), s.end(), notspace)); |
| | | s.erase(std::find_if(s.rbegin(), s.rend(), notspace).base(), s.end()); |
| | | return s; |
| | | } |
| | | |
| | | CProcessJob::CProcessJob(std::string pjId) |
| | | : m_pjId(trimCopy(pjId)) |
| | | { |
| | | clampString(m_pjId, MAX_ID_LEN); |
| | | } |
| | | |
| | | void CProcessJob::setParentCjId(std::string cjId) { |
| | | m_parentCjId = trimCopy(cjId); |
| | | clampString(m_parentCjId, MAX_ID_LEN); |
| | | } |
| | | |
| | | void CProcessJob::setRecipe(RecipeMethod method, std::string spec) { |
| | | m_recipeMethod = method; |
| | | m_recipeSpec = trimCopy(spec); |
| | | clampString(m_recipeSpec, MAX_ID_LEN); |
| | | } |
| | | |
| | | void CProcessJob::addParam(std::string name, std::string value) { |
| | | name = trimCopy(name); |
| | | value = trimCopy(value); |
| | | clampString(name, MAX_PARAM_K); |
| | | clampString(value, MAX_PARAM_V); |
| | | m_params.push_back({ std::move(name), std::move(value) }); |
| | | } |
| | | |
| | | void CProcessJob::setParams(std::vector<PJParam> params) { |
| | | m_params.clear(); |
| | | m_params.reserve(params.size()); |
| | | for (auto& p : params) addParam(std::move(p.name), std::move(p.value)); |
| | | } |
| | | |
| | | void CProcessJob::addPauseEvent(uint32_t ceid) { |
| | | if (ceid) m_pauseEvents.push_back(ceid); |
| | | std::sort(m_pauseEvents.begin(), m_pauseEvents.end()); |
| | | m_pauseEvents.erase(std::unique(m_pauseEvents.begin(), m_pauseEvents.end()), m_pauseEvents.end()); |
| | | } |
| | | |
| | | void CProcessJob::setPauseEvents(std::vector<uint32_t> ceids) { |
| | | m_pauseEvents = std::move(ceids); |
| | | std::sort(m_pauseEvents.begin(), m_pauseEvents.end()); |
| | | m_pauseEvents.erase(std::unique(m_pauseEvents.begin(), m_pauseEvents.end()), m_pauseEvents.end()); |
| | | } |
| | | |
| | | std::vector<CProcessJob::ValidationIssue> |
| | | CProcessJob::validate(const IResourceView& rv) const |
| | | { |
| | | std::vector<ValidationIssue> issues; |
| | | |
| | | // 让 add åæ¶æ¯æ const char* å std::string |
| | | auto add = [&](uint32_t code, std::string msg) { |
| | | issues.push_back({ code, std::move(msg) }); |
| | | }; |
| | | |
| | | // ââ åºæ¬ / æ è¯ ââ |
| | | if (m_pjId.empty()) add(1001, "PJID empty"); |
| | | if (!asciiPrintable(m_pjId)) add(1002, "PJID has non-printable chars"); |
| | | |
| | | if (m_parentCjId.empty()) add(1010, "Parent CJID empty"); |
| | | |
| | | // ââ é
æ¹ï¼RCPSPEC / PPIDï¼ââ |
| | | if (m_recipeSpec.empty()) add(1020, "Recipe spec (PPID) empty"); |
| | | else if (!rv.recipeExists(m_recipeSpec)) { |
| | | add(1021, "PPID not found: " + m_recipeSpec); |
| | | } |
| | | |
| | | // ââ é
æ¹æ¹æ³ vs åæ° ââ 1=NoTuning ç¦æ¢å¸¦åæ°ï¼2=WithTuning å
许/å¯é |
| | | if (m_recipeMethod == RecipeMethod::NoTuning && !m_params.empty()) { |
| | | add(1022, "Params not allowed when PRRECIPEMETHOD=1 (NoTuning)"); |
| | | } |
| | | |
| | | // ââ ç©æéæ©æ ¡éª ââï¼äºéä¸ï¼Carrier+Slots æ MIDsï¼ä¸¤è
é½ä¸å¡«åéè¯¯ï¼ |
| | | const bool hasCarrierSlots = !m_carriers.empty(); |
| | | if (hasCarrierSlots) { |
| | | // {L:n { CARRIERID {L:j SLOTID} }} |
| | | for (const auto& cs : m_carriers) { |
| | | if (cs.carrierId.empty()) { |
| | | add(1030, "CarrierID empty"); |
| | | continue; |
| | | } |
| | | if (!rv.carrierPresent(cs.carrierId)) { |
| | | add(1031, "Carrier not present: " + cs.carrierId); |
| | | } |
| | | if (cs.slots.empty()) { |
| | | add(1032, "No slots specified for carrier: " + cs.carrierId); |
| | | } |
| | | for (auto s : cs.slots) { |
| | | if (s == 0) { |
| | | add(1033, "Slot 0 is invalid for carrier: " + cs.carrierId); |
| | | continue; |
| | | } |
| | | if (!rv.slotUsable(cs.carrierId, s)) { |
| | | add(1034, "Slot unusable: carrier=" + cs.carrierId + " slot=" + std::to_string(s)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else { |
| | | add(1035, "No material selection provided (neither Carrier/Slots nor MIDs)"); |
| | | } |
| | | |
| | | // ââ æåäºä»¶ï¼PRPAUSEEVENTID å表ï¼ââ |
| | | for (auto ceid : m_pauseEvents) { |
| | | if (!rv.ceidDefined(ceid)) { |
| | | add(1050, "Pause CEID unknown: " + std::to_string(ceid)); |
| | | } |
| | | } |
| | | |
| | | return issues; |
| | | } |
| | | |
| | | // ââ ç¶ææº ââ |
| | | // è§åå¯æä½ ä»¬åè®®å¾®è° |
| | | bool CProcessJob::queue() { |
| | | if (m_state != PJState::NoState) return false; |
| | | markQueued(); |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::enterSettingUp() { |
| | | if (m_state != PJState::Queued) return false; |
| | | m_state = PJState::SettingUp; |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::start() { |
| | | if (m_state != PJState::Queued && m_state != PJState::SettingUp && m_state != PJState::Paused) |
| | | return false; |
| | | if (!m_tStart.has_value()) markStart(); |
| | | m_state = PJState::InProcess; |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::pause() { |
| | | if (m_state != PJState::InProcess) return false; |
| | | m_state = PJState::Paused; |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::resume() { |
| | | if (m_state != PJState::Paused) return false; |
| | | m_state = PJState::InProcess; |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::complete() { |
| | | if (m_state != PJState::InProcess && m_state != PJState::Paused) return false; |
| | | m_state = PJState::Completed; |
| | | markEnd(); |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::abort() { |
| | | if (m_state == PJState::Completed || m_state == PJState::Aborted || m_state == PJState::Failed) |
| | | return false; |
| | | m_state = PJState::Aborted; |
| | | markEnd(); |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::fail(std::string reason) { |
| | | m_failReason = trimCopy(reason); |
| | | clampString(m_failReason, 128); |
| | | m_state = PJState::Failed; |
| | | markEnd(); |
| | | return true; |
| | | } |
| | | |
| | | // ââ æ¶é´æ³ & å·¥å
· ââ |
| | | void CProcessJob::markQueued() { |
| | | m_state = PJState::Queued; |
| | | m_tQueued = std::chrono::system_clock::now(); |
| | | } |
| | | |
| | | void CProcessJob::markStart() { |
| | | m_tStart = std::chrono::system_clock::now(); |
| | | } |
| | | |
| | | void CProcessJob::markEnd() { |
| | | m_tEnd = std::chrono::system_clock::now(); |
| | | } |
| | | |
| | | void CProcessJob::clampString(std::string& s, size_t maxLen) { |
| | | if (s.size() > maxLen) s.resize(maxLen); |
| | | } |
| | | |
| | | bool CProcessJob::asciiPrintable(const std::string& s) { |
| | | return std::all_of(s.begin(), s.end(), [](unsigned char c) { |
| | | return c >= 0x20 && c <= 0x7E; |
| | | }); |
| | | } |
| | | |
| | | void CProcessJob::setCarriers(std::vector<CarrierSlotInfo> carriers) |
| | | { |
| | | // ç»ä¸éè¿ addCarrier åè§èåï¼å»ç©ºç½ãæªæãå»éãåå¹¶å carrierï¼ |
| | | m_carriers.clear(); |
| | | m_carriers.reserve(carriers.size()); |
| | | for (auto& cs : carriers) { |
| | | addCarrier(std::move(cs.carrierId), std::move(cs.slots)); |
| | | } |
| | | } |
| | | |
| | | void CProcessJob::addCarrier(std::string carrierId, std::vector<uint8_t> slots) |
| | | { |
| | | // 1) è§èå carrierIdï¼å»ç©ºç½ + é¿åº¦éå¶ |
| | | carrierId = trimCopy(std::move(carrierId)); |
| | | clampString(carrierId, MAX_ID_LEN); |
| | | if (carrierId.empty()) { |
| | | // 空 ID ç´æ¥å¿½ç¥ï¼ä¹å¯ä»¥éæ©æå¼å¸¸/è®°å½æ¥å¿ï¼çä½ é¡¹ç®é£æ ¼ï¼ |
| | | return; |
| | | } |
| | | |
| | | // 2) è§èå slotsï¼å» 0ãæåºãå»é |
| | | // 注ï¼SLOTID æ 1..Nï¼0 è§ä¸ºéæ³/å ä½ |
| | | slots.erase(std::remove(slots.begin(), slots.end(), 0), slots.end()); |
| | | std::sort(slots.begin(), slots.end()); |
| | | slots.erase(std::unique(slots.begin(), slots.end()), slots.end()); |
| | | if (slots.empty()) { |
| | | // æ²¡æææå¡ä½å°±ä¸è¿½å |
| | | return; |
| | | } |
| | | |
| | | // 3) 妿已åå¨ååè½½å
·ï¼ååå¹¶ slot å表 |
| | | auto it = std::find_if(m_carriers.begin(), m_carriers.end(), |
| | | [&](const CarrierSlotInfo& cs) { return cs.carrierId == carrierId; }); |
| | | |
| | | if (it != m_carriers.end()) { |
| | | // åå¹¶ |
| | | it->slots.insert(it->slots.end(), slots.begin(), slots.end()); |
| | | std::sort(it->slots.begin(), it->slots.end()); |
| | | it->slots.erase(std::unique(it->slots.begin(), it->slots.end()), it->slots.end()); |
| | | } |
| | | else { |
| | | // æ°å¢ |
| | | CarrierSlotInfo cs; |
| | | cs.carrierId = std::move(carrierId); |
| | | cs.slots = std::move(slots); |
| | | m_carriers.emplace_back(std::move(cs)); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include <string> |
| | | #include <vector> |
| | | #include <unordered_map> |
| | | #include <unordered_set> |
| | | #include <algorithm> |
| | | #include <cstdint> |
| | | #include <chrono> |
| | | #include <optional> |
| | | |
| | | namespace SERVO { |
| | | /// PJ çå½å¨æï¼è´´è¿ E40 常è§ç¶æï¼ |
| | | enum class PJState : uint8_t { |
| | | NoState = 0, |
| | | Queued, |
| | | SettingUp, |
| | | InProcess, |
| | | Paused, |
| | | Aborting, |
| | | Completed, |
| | | Aborted, |
| | | Failed |
| | | }; |
| | | |
| | | /// é
æ¹æå®æ¹å¼ï¼å¯¹åº S16F15 é PRRECIPEMETHODï¼ |
| | | enum class RecipeMethod : uint8_t { |
| | | NoTuning = 1, // 1 - recipe without variable tuning |
| | | WithTuning = 2 // 2 - recipe with variable tuning |
| | | }; |
| | | |
| | | /// å¯å¨çç¥ï¼å¯¹åº S16F15 é PRPROCESSSTARTï¼ |
| | | enum class StartPolicy : uint8_t { |
| | | Queued = 0, // 建ç«åæé |
| | | AutoStart = 1 // æ¡ä»¶æ»¡è¶³åèªå¨å¯å¨ |
| | | }; |
| | | |
| | | /** é
æ¹åæ°å¯¹ï¼S16F15 ä¸ RCPPARNM / RCPPARVALï¼ */ |
| | | struct PJParam { |
| | | std::string name; // RCPPARNM |
| | | std::string value; // RCPPARVAL |
| | | }; |
| | | |
| | | /** |
| | | {L:2 |
| | | CARRIERID |
| | | {L:j |
| | | SLOTID |
| | | } |
| | | } |
| | | */ |
| | | struct CarrierSlotInfo { |
| | | std::string carrierId; // CARRIERID |
| | | std::vector<uint8_t> slots; // SLOTID[] |
| | | }; |
| | | |
| | | /// ç®åèµæºè§å¾æ¥å£ï¼ä¾ Validate() æ¥è¯¢ï¼ç±è®¾å¤ç«¯å®ç°è
å¨å¤é¨æä¾ï¼ |
| | | struct IResourceView { |
| | | virtual ~IResourceView() = default; |
| | | virtual bool recipeExists(const std::string& ppid) const = 0; |
| | | virtual bool carrierPresent(const std::string& carrierId) const = 0; |
| | | virtual bool slotUsable(const std::string& carrierId, uint16_t slot) const = 0; |
| | | virtual bool ceidDefined(uint32_t ceid) const = 0; |
| | | // ä½ ä¹å¯ä»¥æ©å±ï¼portç¶æãå ç¨æ
åµãCJ/PJ空é´ç |
| | | }; |
| | | |
| | | /// PJ 主类 |
| | | /** |
| | | * ProcessJob ââ ä¸ S16F15ï¼PRJobMultiCreateï¼å段ä¸ä¸å¯¹åºçæ¿è½½ç±» |
| | | * |
| | | * S16F15 ç»æï¼æ ¸å¿èéï¼ï¼ |
| | | * {L:6 |
| | | * PRJOBID -> m_pjId |
| | | * MF -> m_mf |
| | | * {L:n { CARRIERID {L:j SLOTID} } } |
| | | * {L:3 |
| | | * PRRECIPEMETHOD -> m_recipeType |
| | | * RCPSPECï¼PPIDï¼ -> m_recipeSpec |
| | | * {L:m { RCPPARNM RCPPARVAL }} -> m_params |
| | | * } |
| | | * PRPROCESSSTART -> m_startPolicy |
| | | * {L:k PRPAUSEEVENTID} -> m_pauseEvents |
| | | * } |
| | | */ |
| | | class CProcessJob { |
| | | public: |
| | | // ââ æé / åºæ¬è®¾ç½® ââ |
| | | explicit CProcessJob(std::string pjId); |
| | | |
| | | const std::string& id() const noexcept { return m_pjId; } |
| | | const std::string& parentCjId() const noexcept { return m_parentCjId; } |
| | | PJState state() const noexcept { return m_state; } |
| | | StartPolicy startPolicy() const noexcept { return m_startPolicy; } |
| | | RecipeMethod recipeMethod() const noexcept { return m_recipeMethod; } |
| | | const std::string& recipeSpec() const noexcept { return m_recipeSpec; } // PPID æ Spec |
| | | |
| | | // ç»å®ç¶ CJ |
| | | void setParentCjId(std::string cjId); |
| | | |
| | | // é
æ¹ |
| | | void setRecipe(RecipeMethod method, std::string spec); |
| | | |
| | | // å¯å¨çç¥ |
| | | void setStartPolicy(StartPolicy sp) { m_startPolicy = sp; } |
| | | |
| | | // åæ° |
| | | void addParam(std::string name, std::string value); |
| | | void setParams(std::vector<PJParam> params); |
| | | |
| | | // æåäºä»¶ |
| | | void addPauseEvent(uint32_t ceid); |
| | | void setPauseEvents(std::vector<uint32_t> ceids); |
| | | |
| | | // ââ æ ¡éª ââ |
| | | struct ValidationIssue { |
| | | uint32_t code; // èªå®ä¹é误ç |
| | | std::string text; // ææ¬æè¿° |
| | | }; |
| | | // è¿åé®é¢æ¸
åï¼ç©º=éè¿ï¼ |
| | | std::vector<ValidationIssue> validate(const IResourceView& rv) const; |
| | | |
| | | // ââ ç¶ææºï¼å¸¦å®å«ï¼ââ |
| | | bool queue(); // NoState -> Queued |
| | | bool start(); // Queued/SettingUp -> InProcess |
| | | bool enterSettingUp(); // Queued -> SettingUp |
| | | bool pause(); // InProcess -> Paused |
| | | bool resume(); // Paused -> InProcess |
| | | bool complete(); // InProcess -> Completed |
| | | bool abort(); // Any (æªç»æ) -> Aborted |
| | | bool fail(std::string reason); // ä»»ææ -> Failedï¼è®°å½å¤±è´¥åå ï¼ |
| | | |
| | | // ââ 访é®å¨ï¼ç¨äºä¸æ¥/æ¥è¯¢ï¼ââ |
| | | const std::vector<PJParam>& params() const noexcept { return m_params; } |
| | | const std::vector<uint32_t>& pauseEvents() const noexcept { return m_pauseEvents; } |
| | | const std::string& failReason() const noexcept { return m_failReason; } |
| | | |
| | | // æ¶é´æ³ï¼å¯ç¨äºæ¥è¡¨/è¿½æº¯ï¼ |
| | | std::optional<std::chrono::system_clock::time_point> tQueued() const { return m_tQueued; } |
| | | std::optional<std::chrono::system_clock::time_point> tStart() const { return m_tStart; } |
| | | std::optional<std::chrono::system_clock::time_point> tEnd() const { return m_tEnd; } |
| | | |
| | | // é¿åº¦éå¶å·¥å
·ï¼å¯å¨éææ¶ç»ä¸çç¥ï¼ |
| | | static void clampString(std::string& s, size_t maxLen); |
| | | static bool asciiPrintable(const std::string& s); |
| | | |
| | | // æ¸
空并æ´ä½è®¾ç½® |
| | | void setCarriers(std::vector<CarrierSlotInfo> carriers); |
| | | |
| | | // 追å ä¸ä¸ªè½½å
· |
| | | void addCarrier(std::string carrierId, std::vector<uint8_t> slots); |
| | | |
| | | // 访é®å¨ |
| | | const std::vector<CarrierSlotInfo>& carriers() const noexcept { return m_carriers; } |
| | | |
| | | // å¤å®æ¯å¦âæè½½å
·/å¡ä½âæ¹å¼ |
| | | bool usesCarrierSlots() const noexcept { return !m_carriers.empty(); } |
| | | |
| | | |
| | | private: |
| | | // å
é¨ç¶æè½¬ç§»å¸®å© |
| | | void markQueued(); |
| | | void markStart(); |
| | | void markEnd(); |
| | | |
| | | private: |
| | | // æ è¯ |
| | | std::string m_pjId; |
| | | std::string m_parentCjId; |
| | | |
| | | // é
æ¹ |
| | | RecipeMethod m_recipeMethod{ RecipeMethod::NoTuning }; |
| | | std::string m_recipeSpec; // PPID / Spec |
| | | |
| | | // ç©æ |
| | | static constexpr uint8_t MATERIAL_FORMAT = 14; // substrate |
| | | std::vector<CarrierSlotInfo> m_carriers; // {L:n { CARRIERID {L:j SLOTID} }} |
| | | |
| | | // åæ° / æåäºä»¶ |
| | | std::vector<PJParam> m_params; |
| | | std::vector<uint32_t> m_pauseEvents; |
| | | |
| | | // ç¶æ & è®°å½ |
| | | StartPolicy m_startPolicy{ StartPolicy::Queued }; // 0=Queued, 1=AutoStart |
| | | PJState m_state{ PJState::NoState }; |
| | | std::string m_failReason; |
| | | |
| | | // æ¶é´æ³ |
| | | std::optional<std::chrono::system_clock::time_point> m_tQueued; |
| | | std::optional<std::chrono::system_clock::time_point> m_tStart; |
| | | std::optional<std::chrono::system_clock::time_point> m_tEnd; |
| | | |
| | | // 约æï¼å¯æä½ 们åè®®è°æ´ï¼ |
| | | static constexpr size_t MAX_ID_LEN = 64; // PJID/ CJID/ CarrierID/ MID/ PPID |
| | | static constexpr size_t MAX_PARAM_K = 32; // åæ°å |
| | | static constexpr size_t MAX_PARAM_V = 64; // åæ°å¼ |
| | | }; |
| | | } |
| | | |
| | | |
| | |
| | | #define IDD_DIALOG_ADD_IDS 135 |
| | | #define IDD_DIALOG_LINK_REPORT 137 |
| | | #define IDD_DIALOG_LINK_REPORT_DETAIL 139 |
| | | #define IDD_DIALOG_PJS 141 |
| | | #define IDC_EDIT_LOG 1000 |
| | | #define IDC_EDIT_IP 1001 |
| | | #define IDC_EDIT_PORT 1002 |
| | |
| | | #define IDC_BUTTON_CARRIER_RELEASE 1036 |
| | | #define IDC_BUTTON_QUERY_CJ_SPACE 1037 |
| | | #define IDC_BUTTON_QUERY_PJ_SPACE 1038 |
| | | #define IDC_BUTTON_CREATE_PJ 1039 |
| | | #define IDC_BUTTON_ADD 1040 |
| | | #define IDC_BUTTON_DELETE 1041 |
| | | |
| | | // Next default values for new objects |
| | | // |
| | | #ifdef APSTUDIO_INVOKED |
| | | #ifndef APSTUDIO_READONLY_SYMBOLS |
| | | #define _APS_NEXT_RESOURCE_VALUE 141 |
| | | #define _APS_NEXT_RESOURCE_VALUE 143 |
| | | #define _APS_NEXT_COMMAND_VALUE 32771 |
| | | #define _APS_NEXT_CONTROL_VALUE 1039 |
| | | #define _APS_NEXT_CONTROL_VALUE 1042 |
| | | #define _APS_NEXT_SYMED_VALUE 101 |
| | | #endif |
| | | #endif |
| | |
| | | |
| | | |
| | | // æ¨¡ææµè¯ |
| | | /* |
| | | if (m_nIndex == 0) { |
| | | static int ii = 0; |
| | | ii++; |
| | |
| | | CPortStatusReport portStatusReport; |
| | | portStatusReport.setPortStatus(PORT_INUSE); |
| | | portStatusReport.setJobExistenceSlot(0xf); |
| | | portStatusReport.setCassetteId("CID1984113"); |
| | | portStatusReport.setCassetteId("CID1001"); |
| | | int nRet = portStatusReport.serialize(szBuffer, 64); |
| | | decodePortStatusReport(pStep, szBuffer, 64); |
| | | } |
| | | } |
| | | */ |
| | | if (m_nIndex == 1) { |
| | | static int ii = 0; |
| | | ii++; |
| | | if (ii == 55) { |
| | | char szBuffer[64] = { 0 }; |
| | | CStep* pStep = getStepWithName(STEP_EQ_PORT1_INUSE); |
| | | CPortStatusReport portStatusReport; |
| | | portStatusReport.setPortStatus(PORT_INUSE); |
| | | portStatusReport.setJobExistenceSlot(0xf); |
| | | portStatusReport.setCassetteId("CID1004"); |
| | | int nRet = portStatusReport.serialize(szBuffer, 64); |
| | | decodePortStatusReport(pStep, szBuffer, 64); |
| | | } |
| | | } |
| | | } |
| | | |
| | | void CLoadPort::serialize(CArchive& ar) |
| | |
| | | #include "CMaster.h" |
| | | #include <future> |
| | | #include <vector> |
| | | #include "RecipeManager.h" |
| | | |
| | | |
| | | namespace SERVO { |
| | |
| | | |
| | | CMaster::~CMaster() |
| | | { |
| | | for (auto item : m_processJobs) { |
| | | delete item; |
| | | } |
| | | m_processJobs.clear(); |
| | | |
| | | if (m_hEventReadBitsThreadExit[0] != nullptr) { |
| | | ::CloseHandle(m_hEventReadBitsThreadExit[0]); |
| | | m_hEventReadBitsThreadExit[0] = nullptr; |
| | |
| | | return nullptr; |
| | | } |
| | | |
| | | CEquipment* CMaster::getEquipment(int id) const |
| | | { |
| | | for (auto item : m_listEquipment) { |
| | | if (item->getID() == id) return item; |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | /* |
| | | * æ·»å LoadPort1 |
| | | * index -- 0~3 |
| | |
| | | { |
| | | m_nContinuousTransferCount = round; |
| | | } |
| | | |
| | | int CMaster::setProcessJobs(std::vector<SERVO::CProcessJob*>& pjs) |
| | | { |
| | | std::vector<SERVO::CProcessJob*> temp; |
| | | for (auto p : pjs) { |
| | | if (p->validate(*this)) { |
| | | temp.push_back(p); |
| | | } |
| | | } |
| | | |
| | | m_processJobs = temp; |
| | | return m_processJobs.size(); |
| | | } |
| | | |
| | | CLoadPort* CMaster::getPortWithCarrierId(const std::string& carrierId) const |
| | | { |
| | | CLoadPort* pPort; |
| | | int eqid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4}; |
| | | for (int i = 0; i < 4; i++) { |
| | | pPort = (CLoadPort*)getEquipment(eqid[i]); |
| | | ASSERT(pPort); |
| | | if (pPort->getCassetteId().compare(carrierId) == 0) return pPort; |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | bool CMaster::isProcessJobsEmpty() const |
| | | { |
| | | return m_processJobs.empty(); |
| | | } |
| | | |
| | | bool CMaster::recipeExists(const std::string& ppid) const |
| | | { |
| | | std::vector<std::string> vecRecipe = RecipeManager::getInstance().getAllPPID(); |
| | | bool exists = std::find(vecRecipe.begin(), vecRecipe.end(), ppid) != vecRecipe.end(); |
| | | return exists; |
| | | } |
| | | |
| | | bool CMaster::carrierPresent(const std::string& carrierId) const |
| | | { |
| | | CLoadPort* pPort = getPortWithCarrierId(carrierId); |
| | | return pPort != nullptr; |
| | | } |
| | | |
| | | bool CMaster::slotUsable(const std::string& carrierId, uint16_t slot) const |
| | | { |
| | | CLoadPort* pPort = getPortWithCarrierId(carrierId); |
| | | if(pPort == nullptr) return false; |
| | | CSlot* pSlot = pPort->getSlot(slot); |
| | | if (pSlot == nullptr) return false; |
| | | return pSlot->isEnable(); |
| | | } |
| | | |
| | | bool CMaster::ceidDefined(uint32_t ceid) const |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | } |
| | |
| | | #include "CArmTray.h" |
| | | #include "CCLinkIEControl.h" |
| | | #include "CRobotTask.h" |
| | | |
| | | #include "ProcessJob.h" |
| | | |
| | | |
| | | #define CTStep_Unknow 0 |
| | |
| | | ONCTROUNDEND onCTRoundEnd; |
| | | } MasterListener; |
| | | |
| | | class CMaster |
| | | class CMaster : public IResourceView |
| | | { |
| | | public: |
| | | CMaster(); |
| | |
| | | void onTimer(UINT nTimerid); |
| | | std::list<CEquipment*>& getEquipmentList(); |
| | | CEquipment* getEquipment(int id); |
| | | CEquipment* getEquipment(int id) const; |
| | | void setCacheFilepath(const char* pszFilepath); |
| | | int abortCurrentTask(); |
| | | int restoreCurrentTask(); |
| | |
| | | int carrierRelease(unsigned int port); |
| | | int getContinuousTransferCount(); |
| | | void setContinuousTransferCount(int round); |
| | | int setProcessJobs(std::vector<SERVO::CProcessJob*>& pjs); |
| | | CLoadPort* getPortWithCarrierId(const std::string& carrierId) const; |
| | | |
| | | private: |
| | | inline void lock() { EnterCriticalSection(&m_criticalSection); } |
| | |
| | | CRobotTask* createTransferTask_restore(CEquipment* pEqSrc, CLoadPort** pPorts); |
| | | CRobotTask* createTransferTask_continuous_transfer(CEquipment* pSrcEq, int nSrcSlot, |
| | | CEquipment* pTarEq, int nTarSlot, int armNo = 1); |
| | | |
| | | public: |
| | | // ââ IResourceView è¦å ââï¼æ³¨æ constï¼ |
| | | bool isProcessJobsEmpty() const override; |
| | | bool recipeExists(const std::string& ppid) const override; |
| | | 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; |
| | | |
| | | private: |
| | | CRITICAL_SECTION m_criticalSection; |
| | |
| | | private: |
| | | bool m_bEnableEventReport; |
| | | bool m_bEnableAlarmReport; |
| | | std::vector<SERVO::CProcessJob*> m_processJobs; |
| | | }; |
| | | } |
| | | |
| | |
| | | else if (nStream == 10 && pHeader->function == 3) { |
| | | replyTerminalDisplay(pMessage); |
| | | } |
| | | else if (nStream == 16 && pHeader->function == 15) { |
| | | replyPRJobMultiCreate(pMessage); |
| | | } |
| | | }; |
| | | |
| | | PassiveListener listener; |
| | |
| | | return 0; |
| | | } |
| | | |
| | | // S16F15 |
| | | int CHsmsPassive::replyPRJobMultiCreate(IMessage* pRecv) |
| | | { |
| | | if (m_pPassive == NULL || STATE::SELECTED != m_pPassive->getState()) { |
| | | return ER_NOTSELECT; |
| | | } |
| | | ISECS2Item* pBody = pRecv->getBody(); |
| | | if (pBody == nullptr || pBody->getType() != SITYPE::L) ER_PARAM_ERROR; |
| | | |
| | | |
| | | // è§£éæ°æ®ï¼å¾å°CProcessJob |
| | | ISECS2Item* pItemPjs, * pItemPj,* pItemCarriers, * pItemCarrier, *pItemSlots, *pItemRecipes; |
| | | unsigned int DATAID; |
| | | const char* pszPrjobid, *pszMF, *pszCarrierId, *pszRecipeName; |
| | | std::string strCarrierId; |
| | | unsigned int len; |
| | | unsigned char slot, PRRECIPEMETHOD; |
| | | std::vector<unsigned char> slots; |
| | | std::vector<SERVO::CProcessJob*> pjs; |
| | | |
| | | if (!pBody->getSubItemU4(0, DATAID)) return ER_PARAM_ERROR; |
| | | pItemPjs = pBody->getSubItem(1); |
| | | if (pItemPjs == nullptr) return ER_PARAM_ERROR; |
| | | for (int i = 0; i < pItemPjs->getSubItemSize(); i++) { |
| | | pItemPj = pItemPjs->getSubItem(i); |
| | | if (pItemPj == nullptr) continue; |
| | | if (!pItemPj->getSubItemString(0, pszPrjobid)) continue; |
| | | if (!pItemPj->getSubItemBinary(1, pszMF, len)) continue; |
| | | pItemCarriers = pItemPj->getSubItem(2); |
| | | if (pItemCarriers == nullptr) continue; |
| | | pItemRecipes = pItemPj->getSubItem(3); |
| | | if (pItemRecipes == nullptr) continue; |
| | | SERVO::CProcessJob* pj = new SERVO::CProcessJob(pszPrjobid); |
| | | int size = pItemCarriers->getSubItemSize(); |
| | | for (int j = 0; j < size; j++) { |
| | | pItemCarrier = pItemCarriers->getSubItem(j); |
| | | strCarrierId.clear(); |
| | | if (pItemCarrier->getSubItemString(0, pszCarrierId)) { |
| | | strCarrierId = pszCarrierId; |
| | | } |
| | | |
| | | slots.clear(); |
| | | pItemSlots = pItemCarrier->getSubItem(1); |
| | | if (pItemSlots != nullptr) { |
| | | int size2 = pItemSlots->getSubItemSize(); |
| | | for (int k = 0; k < size2; k++) { |
| | | if (pItemSlots->getSubItemU1(k, slot)) { |
| | | slots.push_back(slot); |
| | | } |
| | | } |
| | | } |
| | | pj->addCarrier(strCarrierId, slots); |
| | | } |
| | | if (pItemRecipes->getSubItemU1(0, PRRECIPEMETHOD) |
| | | && pItemRecipes->getSubItemString(1, pszRecipeName)) { |
| | | pj->setRecipe(SERVO::RecipeMethod(PRRECIPEMETHOD), std::string(pszRecipeName)); |
| | | } |
| | | |
| | | pjs.push_back(pj); |
| | | } |
| | | |
| | | ASSERT(m_listener.onPRJobMultiCreate != nullptr); |
| | | int nRet = m_listener.onPRJobMultiCreate(this, pjs); |
| | | |
| | | |
| | | // å夿¥æ |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 16, 16, ++m_nSystemByte); |
| | | ASSERT(pMessage); |
| | | ISECS2Item* pItemPrjobIds = pMessage->getBody()->addItem(); |
| | | ISECS2Item* pItemErrors = pMessage->getBody()->addItem(); |
| | | bool bHasError = false; |
| | | for (auto p : pjs) { |
| | | if (p->issue().empty()) { |
| | | pItemPrjobIds->addItem(p->id().c_str(), "PRJOBID"); |
| | | } |
| | | else { |
| | | bHasError = true; |
| | | } |
| | | } |
| | | if (bHasError) { |
| | | pItemErrors->addBoolItem(false, "ACKA"); |
| | | ISECS2Item* pItemErrors2 = pItemErrors->addItem(); |
| | | for (auto p : pjs) { |
| | | if (!p->issue().empty()) { |
| | | ISECS2Item* pItemErr = pItemErrors2->addItem(); |
| | | pItemErr->addU4Item(p->issue()[0].code, "ERRCODE"); |
| | | pItemErr->addItem(("<" + p->id() + ">" + p->issue()[0].text).c_str(), "ERRTEXT"); |
| | | } |
| | | } |
| | | } |
| | | m_pPassive->sendMessage(pMessage); |
| | | LOGI("<HSMS>[SECS Msg SEND]S16F16 (SysByte=%u)", pMessage->getHeader()->systemBytes); |
| | | HSMS_Destroy1Message(pMessage); |
| | | |
| | | |
| | | // éæ¾æé®é¢(æªæ·»å å°master)çå
å |
| | | for (auto p : pjs) { |
| | | if(!p->issue().empty()) delete p; |
| | | } |
| | | pjs.clear(); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | // S5F1 |
| | | int CHsmsPassive::requestAlarmReport(int ALCD, int ALID, const char* ALTX) |
| | | { |
| | |
| | | #include <map> |
| | | #include <set> |
| | | #include "CCollectionEvent.h" |
| | | #include "ProcessJob.h" |
| | | |
| | | |
| | | #define EQCONSTANT_VALUE_MAX 64 |
| | |
| | | const char* pszCarrierId, |
| | | unsigned char PTN, |
| | | std::string& strErrorTxt)> CARRIERACTION; |
| | | typedef std::function<int(void* pFrom, std::vector<SERVO::CProcessJob*>& pjs)> PRJOBMULTICREATE; |
| | | typedef struct _SECSListener |
| | | { |
| | | SECSEQOFFLINE onEQOffLine; |
| | |
| | | EDALARMREPORT onEnableDisableAlarmReport; |
| | | QUERYPPIDLIST onQueryPPIDList; |
| | | CARRIERACTION onCarrierAction; |
| | | PRJOBMULTICREATE onPRJobMultiCreate; |
| | | } SECSListener; |
| | | |
| | | |
| | |
| | | int replyPurgeSpooledData(IMessage* pRecv); |
| | | int replyQueryPPIDList(IMessage* pRecv); |
| | | int replyTerminalDisplay(IMessage* pRecv); |
| | | int replyPRJobMultiCreate(IMessage* pRecv); |
| | | |
| | | private: |
| | | inline void Lock() { EnterCriticalSection(&m_criticalSection); } |
| | |
| | | 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()); |
| | | } |
| | | return m_master.setProcessJobs(pjs); |
| | | }; |
| | | m_hsmsPassive.setListener(listener); |
| | | m_hsmsPassive.setEquipmentModelType((LPTSTR)(LPCTSTR)strModeType); |
| | | m_hsmsPassive.setSoftRev((LPTSTR)(LPCTSTR)strSoftRev); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "ProcessJob.h" |
| | | #include <cctype> |
| | | |
| | | namespace SERVO { |
| | | static inline std::string trimCopy(std::string s) { |
| | | auto notspace = [](int ch) { return !std::isspace(ch); }; |
| | | s.erase(s.begin(), std::find_if(s.begin(), s.end(), notspace)); |
| | | s.erase(std::find_if(s.rbegin(), s.rend(), notspace).base(), s.end()); |
| | | return s; |
| | | } |
| | | |
| | | CProcessJob::CProcessJob(std::string pjId) |
| | | : m_pjId(trimCopy(pjId)) |
| | | { |
| | | clampString(m_pjId, MAX_ID_LEN); |
| | | } |
| | | |
| | | void CProcessJob::setParentCjId(std::string cjId) { |
| | | m_parentCjId = trimCopy(cjId); |
| | | clampString(m_parentCjId, MAX_ID_LEN); |
| | | } |
| | | |
| | | void CProcessJob::setRecipe(RecipeMethod method, std::string spec) { |
| | | m_recipeMethod = method; |
| | | m_recipeSpec = trimCopy(spec); |
| | | clampString(m_recipeSpec, MAX_ID_LEN); |
| | | } |
| | | |
| | | void CProcessJob::addParam(std::string name, std::string value) { |
| | | name = trimCopy(name); |
| | | value = trimCopy(value); |
| | | clampString(name, MAX_PARAM_K); |
| | | clampString(value, MAX_PARAM_V); |
| | | m_params.push_back({ std::move(name), std::move(value) }); |
| | | } |
| | | |
| | | void CProcessJob::setParams(std::vector<PJParam> params) { |
| | | m_params.clear(); |
| | | m_params.reserve(params.size()); |
| | | for (auto& p : params) addParam(std::move(p.name), std::move(p.value)); |
| | | } |
| | | |
| | | void CProcessJob::addPauseEvent(uint32_t ceid) { |
| | | if (ceid) m_pauseEvents.push_back(ceid); |
| | | std::sort(m_pauseEvents.begin(), m_pauseEvents.end()); |
| | | m_pauseEvents.erase(std::unique(m_pauseEvents.begin(), m_pauseEvents.end()), m_pauseEvents.end()); |
| | | } |
| | | |
| | | void CProcessJob::setPauseEvents(std::vector<uint32_t> ceids) { |
| | | m_pauseEvents = std::move(ceids); |
| | | std::sort(m_pauseEvents.begin(), m_pauseEvents.end()); |
| | | m_pauseEvents.erase(std::unique(m_pauseEvents.begin(), m_pauseEvents.end()), m_pauseEvents.end()); |
| | | } |
| | | |
| | | const std::vector<CProcessJob::ValidationIssue>& CProcessJob::issue() |
| | | { |
| | | return m_issues; |
| | | } |
| | | |
| | | bool CProcessJob::validate(const IResourceView& rv) |
| | | { |
| | | m_issues.clear(); |
| | | |
| | | // 让 add åæ¶æ¯æ const char* å std::string |
| | | 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"); |
| | | if (!asciiPrintable(m_pjId)) add(1002, "PJID has non-printable chars"); |
| | | |
| | | // if (m_parentCjId.empty()) add(1010, "Parent CJID empty"); |
| | | |
| | | // ââ é
æ¹ï¼RCPSPEC / PPIDï¼ââ |
| | | if (m_recipeSpec.empty()) add(1020, "Recipe spec (PPID) empty"); |
| | | else if (!rv.recipeExists(m_recipeSpec)) { |
| | | add(1021, "PPID not found: " + m_recipeSpec); |
| | | } |
| | | |
| | | // ââ é
æ¹æ¹æ³ vs åæ° ââ 1=NoTuning ç¦æ¢å¸¦åæ°ï¼2=WithTuning å
许/å¯é |
| | | if (m_recipeMethod == RecipeMethod::NoTuning && !m_params.empty()) { |
| | | add(1022, "Params not allowed when PRRECIPEMETHOD=1 (NoTuning)"); |
| | | } |
| | | |
| | | // ââ ç©æéæ©æ ¡éª ââï¼äºéä¸ï¼Carrier+Slots æ MIDsï¼ä¸¤è
é½ä¸å¡«åéè¯¯ï¼ |
| | | const bool hasCarrierSlots = !m_carriers.empty(); |
| | | if (hasCarrierSlots) { |
| | | // {L:n { CARRIERID {L:j SLOTID} }} |
| | | for (const auto& cs : m_carriers) { |
| | | if (cs.carrierId.empty()) { |
| | | add(1030, "CarrierID empty"); |
| | | continue; |
| | | } |
| | | if (!rv.carrierPresent(cs.carrierId)) { |
| | | add(1031, "Carrier not present: " + cs.carrierId); |
| | | } |
| | | if (cs.slots.empty()) { |
| | | add(1032, "No slots specified for carrier: " + cs.carrierId); |
| | | } |
| | | for (auto s : cs.slots) { |
| | | if (s == 0) { |
| | | add(1033, "Slot 0 is invalid for carrier: " + cs.carrierId); |
| | | continue; |
| | | } |
| | | if (!rv.slotUsable(cs.carrierId, s)) { |
| | | add(1034, "Slot unusable: carrier=" + cs.carrierId + " slot=" + std::to_string(s)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else { |
| | | add(1035, "No material selection provided (neither Carrier/Slots nor MIDs)"); |
| | | } |
| | | |
| | | // ââ æåäºä»¶ï¼PRPAUSEEVENTID å表ï¼ââ |
| | | for (auto ceid : m_pauseEvents) { |
| | | if (!rv.ceidDefined(ceid)) { |
| | | add(1050, "Pause CEID unknown: " + std::to_string(ceid)); |
| | | } |
| | | } |
| | | |
| | | return m_issues.empty(); |
| | | } |
| | | |
| | | // ââ ç¶ææº ââ |
| | | // è§åå¯æä½ ä»¬åè®®å¾®è° |
| | | bool CProcessJob::queue() { |
| | | if (m_state != PJState::NoState) return false; |
| | | markQueued(); |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::enterSettingUp() { |
| | | if (m_state != PJState::Queued) return false; |
| | | m_state = PJState::SettingUp; |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::start() { |
| | | if (m_state != PJState::Queued && m_state != PJState::SettingUp && m_state != PJState::Paused) |
| | | return false; |
| | | if (!m_tStart.has_value()) markStart(); |
| | | m_state = PJState::InProcess; |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::pause() { |
| | | if (m_state != PJState::InProcess) return false; |
| | | m_state = PJState::Paused; |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::resume() { |
| | | if (m_state != PJState::Paused) return false; |
| | | m_state = PJState::InProcess; |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::complete() { |
| | | if (m_state != PJState::InProcess && m_state != PJState::Paused) return false; |
| | | m_state = PJState::Completed; |
| | | markEnd(); |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::abort() { |
| | | if (m_state == PJState::Completed || m_state == PJState::Aborted || m_state == PJState::Failed) |
| | | return false; |
| | | m_state = PJState::Aborted; |
| | | markEnd(); |
| | | return true; |
| | | } |
| | | |
| | | bool CProcessJob::fail(std::string reason) { |
| | | m_failReason = trimCopy(reason); |
| | | clampString(m_failReason, 128); |
| | | m_state = PJState::Failed; |
| | | markEnd(); |
| | | return true; |
| | | } |
| | | |
| | | // ââ æ¶é´æ³ & å·¥å
· ââ |
| | | void CProcessJob::markQueued() { |
| | | m_state = PJState::Queued; |
| | | m_tQueued = std::chrono::system_clock::now(); |
| | | } |
| | | |
| | | void CProcessJob::markStart() { |
| | | m_tStart = std::chrono::system_clock::now(); |
| | | } |
| | | |
| | | void CProcessJob::markEnd() { |
| | | m_tEnd = std::chrono::system_clock::now(); |
| | | } |
| | | |
| | | void CProcessJob::clampString(std::string& s, size_t maxLen) { |
| | | if (s.size() > maxLen) s.resize(maxLen); |
| | | } |
| | | |
| | | bool CProcessJob::asciiPrintable(const std::string& s) { |
| | | return std::all_of(s.begin(), s.end(), [](unsigned char c) { |
| | | return c >= 0x20 && c <= 0x7E; |
| | | }); |
| | | } |
| | | |
| | | void CProcessJob::setCarriers(std::vector<CarrierSlotInfo> carriers) |
| | | { |
| | | // ç»ä¸éè¿ addCarrier åè§èåï¼å»ç©ºç½ãæªæãå»éãåå¹¶å carrierï¼ |
| | | m_carriers.clear(); |
| | | m_carriers.reserve(carriers.size()); |
| | | for (auto& cs : carriers) { |
| | | addCarrier(std::move(cs.carrierId), std::move(cs.slots)); |
| | | } |
| | | } |
| | | |
| | | void CProcessJob::addCarrier(std::string carrierId, std::vector<uint8_t> slots) |
| | | { |
| | | // 1) è§èå carrierIdï¼å»ç©ºç½ + é¿åº¦éå¶ |
| | | carrierId = trimCopy(std::move(carrierId)); |
| | | clampString(carrierId, MAX_ID_LEN); |
| | | if (carrierId.empty()) { |
| | | // 空 ID ç´æ¥å¿½ç¥ï¼ä¹å¯ä»¥éæ©æå¼å¸¸/è®°å½æ¥å¿ï¼çä½ é¡¹ç®é£æ ¼ï¼ |
| | | return; |
| | | } |
| | | |
| | | // 2) è§èå slotsï¼å» 0ãæåºãå»é |
| | | // 注ï¼SLOTID æ 1..Nï¼0 è§ä¸ºéæ³/å ä½ |
| | | slots.erase(std::remove(slots.begin(), slots.end(), 0), slots.end()); |
| | | std::sort(slots.begin(), slots.end()); |
| | | slots.erase(std::unique(slots.begin(), slots.end()), slots.end()); |
| | | if (slots.empty()) { |
| | | // æ²¡æææå¡ä½å°±ä¸è¿½å |
| | | return; |
| | | } |
| | | |
| | | // 3) 妿已åå¨ååè½½å
·ï¼ååå¹¶ slot å表 |
| | | auto it = std::find_if(m_carriers.begin(), m_carriers.end(), |
| | | [&](const CarrierSlotInfo& cs) { return cs.carrierId == carrierId; }); |
| | | |
| | | if (it != m_carriers.end()) { |
| | | // åå¹¶ |
| | | it->slots.insert(it->slots.end(), slots.begin(), slots.end()); |
| | | std::sort(it->slots.begin(), it->slots.end()); |
| | | it->slots.erase(std::unique(it->slots.begin(), it->slots.end()), it->slots.end()); |
| | | } |
| | | else { |
| | | // æ°å¢ |
| | | CarrierSlotInfo cs; |
| | | cs.carrierId = std::move(carrierId); |
| | | cs.slots = std::move(slots); |
| | | m_carriers.emplace_back(std::move(cs)); |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include <string> |
| | | #include <vector> |
| | | #include <unordered_map> |
| | | #include <unordered_set> |
| | | #include <algorithm> |
| | | #include <cstdint> |
| | | #include <chrono> |
| | | #include <optional> |
| | | |
| | | namespace SERVO { |
| | | /// PJ çå½å¨æï¼è´´è¿ E40 常è§ç¶æï¼ |
| | | enum class PJState : uint8_t { |
| | | NoState = 0, |
| | | Queued, |
| | | SettingUp, |
| | | InProcess, |
| | | Paused, |
| | | Aborting, |
| | | Completed, |
| | | Aborted, |
| | | Failed |
| | | }; |
| | | |
| | | /// é
æ¹æå®æ¹å¼ï¼å¯¹åº S16F15 é PRRECIPEMETHODï¼ |
| | | enum class RecipeMethod : uint8_t { |
| | | NoTuning = 1, // 1 - recipe without variable tuning |
| | | WithTuning = 2 // 2 - recipe with variable tuning |
| | | }; |
| | | |
| | | /// å¯å¨çç¥ï¼å¯¹åº S16F15 é PRPROCESSSTARTï¼ |
| | | enum class StartPolicy : uint8_t { |
| | | Queued = 0, // 建ç«åæé |
| | | AutoStart = 1 // æ¡ä»¶æ»¡è¶³åèªå¨å¯å¨ |
| | | }; |
| | | |
| | | /** é
æ¹åæ°å¯¹ï¼S16F15 ä¸ RCPPARNM / RCPPARVALï¼ */ |
| | | struct PJParam { |
| | | std::string name; // RCPPARNM |
| | | std::string value; // RCPPARVAL |
| | | }; |
| | | |
| | | /** |
| | | {L:2 |
| | | CARRIERID |
| | | {L:j |
| | | SLOTID |
| | | } |
| | | } |
| | | */ |
| | | struct CarrierSlotInfo { |
| | | std::string carrierId; // CARRIERID |
| | | std::vector<uint8_t> slots; // SLOTID[] |
| | | }; |
| | | |
| | | /// ç®åèµæºè§å¾æ¥å£ï¼ä¾ Validate() æ¥è¯¢ï¼ç±è®¾å¤ç«¯å®ç°è
å¨å¤é¨æä¾ï¼ |
| | | struct IResourceView { |
| | | virtual ~IResourceView() = default; |
| | | virtual bool isProcessJobsEmpty() const = 0; |
| | | virtual bool recipeExists(const std::string& ppid) const = 0; |
| | | virtual bool carrierPresent(const std::string& carrierId) const = 0; |
| | | virtual bool slotUsable(const std::string& carrierId, uint16_t slot) const = 0; |
| | | virtual bool ceidDefined(uint32_t ceid) const = 0; |
| | | // ä½ ä¹å¯ä»¥æ©å±ï¼portç¶æãå ç¨æ
åµãCJ/PJ空é´ç |
| | | }; |
| | | |
| | | /// PJ 主类 |
| | | /** |
| | | * ProcessJob ââ ä¸ S16F15ï¼PRJobMultiCreateï¼å段ä¸ä¸å¯¹åºçæ¿è½½ç±» |
| | | * |
| | | * S16F15 ç»æï¼æ ¸å¿èéï¼ï¼ |
| | | * {L:6 |
| | | * PRJOBID -> m_pjId |
| | | * MF -> m_mf |
| | | * {L:n { CARRIERID {L:j SLOTID} } } |
| | | * {L:3 |
| | | * PRRECIPEMETHOD -> m_recipeType |
| | | * RCPSPECï¼PPIDï¼ -> m_recipeSpec |
| | | * {L:m { RCPPARNM RCPPARVAL }} -> m_params |
| | | * } |
| | | * PRPROCESSSTART -> m_startPolicy |
| | | * {L:k PRPAUSEEVENTID} -> m_pauseEvents |
| | | * } |
| | | */ |
| | | class CProcessJob { |
| | | public: |
| | | // ââ æé / åºæ¬è®¾ç½® ââ |
| | | explicit CProcessJob(std::string pjId); |
| | | |
| | | const std::string& id() const noexcept { return m_pjId; } |
| | | const std::string& parentCjId() const noexcept { return m_parentCjId; } |
| | | PJState state() const noexcept { return m_state; } |
| | | StartPolicy startPolicy() const noexcept { return m_startPolicy; } |
| | | RecipeMethod recipeMethod() const noexcept { return m_recipeMethod; } |
| | | const std::string& recipeSpec() const noexcept { return m_recipeSpec; } // PPID æ Spec |
| | | |
| | | // ç»å®ç¶ CJ |
| | | void setParentCjId(std::string cjId); |
| | | |
| | | // é
æ¹ |
| | | void setRecipe(RecipeMethod method, std::string spec); |
| | | |
| | | // å¯å¨çç¥ |
| | | void setStartPolicy(StartPolicy sp) { m_startPolicy = sp; } |
| | | |
| | | // åæ° |
| | | void addParam(std::string name, std::string value); |
| | | void setParams(std::vector<PJParam> params); |
| | | |
| | | // æåäºä»¶ |
| | | void addPauseEvent(uint32_t ceid); |
| | | void setPauseEvents(std::vector<uint32_t> ceids); |
| | | |
| | | // ââ æ ¡éª ââ |
| | | struct ValidationIssue { |
| | | uint32_t code; // èªå®ä¹é误ç |
| | | std::string text; // ææ¬æè¿° |
| | | }; |
| | | // è¿åé®é¢æ¸
åï¼ç©º=éè¿ï¼ |
| | | bool validate(const IResourceView& rv); |
| | | const std::vector<ValidationIssue>& issue(); |
| | | |
| | | // ââ ç¶ææºï¼å¸¦å®å«ï¼ââ |
| | | bool queue(); // NoState -> Queued |
| | | bool start(); // Queued/SettingUp -> InProcess |
| | | bool enterSettingUp(); // Queued -> SettingUp |
| | | bool pause(); // InProcess -> Paused |
| | | bool resume(); // Paused -> InProcess |
| | | bool complete(); // InProcess -> Completed |
| | | bool abort(); // Any (æªç»æ) -> Aborted |
| | | bool fail(std::string reason); // ä»»ææ -> Failedï¼è®°å½å¤±è´¥åå ï¼ |
| | | |
| | | // ââ 访é®å¨ï¼ç¨äºä¸æ¥/æ¥è¯¢ï¼ââ |
| | | const std::vector<PJParam>& params() const noexcept { return m_params; } |
| | | const std::vector<uint32_t>& pauseEvents() const noexcept { return m_pauseEvents; } |
| | | const std::string& failReason() const noexcept { return m_failReason; } |
| | | |
| | | // æ¶é´æ³ï¼å¯ç¨äºæ¥è¡¨/è¿½æº¯ï¼ |
| | | std::optional<std::chrono::system_clock::time_point> tQueued() const { return m_tQueued; } |
| | | std::optional<std::chrono::system_clock::time_point> tStart() const { return m_tStart; } |
| | | std::optional<std::chrono::system_clock::time_point> tEnd() const { return m_tEnd; } |
| | | |
| | | // é¿åº¦éå¶å·¥å
·ï¼å¯å¨éææ¶ç»ä¸çç¥ï¼ |
| | | static void clampString(std::string& s, size_t maxLen); |
| | | static bool asciiPrintable(const std::string& s); |
| | | |
| | | // æ¸
空并æ´ä½è®¾ç½® |
| | | void setCarriers(std::vector<CarrierSlotInfo> carriers); |
| | | |
| | | // 追å ä¸ä¸ªè½½å
· |
| | | void addCarrier(std::string carrierId, std::vector<uint8_t> slots); |
| | | |
| | | // 访é®å¨ |
| | | const std::vector<CarrierSlotInfo>& carriers() const noexcept { return m_carriers; } |
| | | |
| | | // å¤å®æ¯å¦âæè½½å
·/å¡ä½âæ¹å¼ |
| | | bool usesCarrierSlots() const noexcept { return !m_carriers.empty(); } |
| | | |
| | | |
| | | private: |
| | | // å
é¨ç¶æè½¬ç§»å¸®å© |
| | | void markQueued(); |
| | | void markStart(); |
| | | void markEnd(); |
| | | |
| | | private: |
| | | // æ è¯ |
| | | std::string m_pjId; |
| | | std::string m_parentCjId; |
| | | |
| | | // é
æ¹ |
| | | RecipeMethod m_recipeMethod{ RecipeMethod::NoTuning }; |
| | | std::string m_recipeSpec; // PPID / Spec |
| | | |
| | | // ç©æ |
| | | static constexpr uint8_t MATERIAL_FORMAT = 14; // substrate |
| | | std::vector<CarrierSlotInfo> m_carriers; // {L:n { CARRIERID {L:j SLOTID} }} |
| | | |
| | | // åæ° / æåäºä»¶ |
| | | std::vector<PJParam> m_params; |
| | | std::vector<uint32_t> m_pauseEvents; |
| | | |
| | | // ç¶æ & è®°å½ |
| | | StartPolicy m_startPolicy{ StartPolicy::Queued }; // 0=Queued, 1=AutoStart |
| | | PJState m_state{ PJState::NoState }; |
| | | std::string m_failReason; |
| | | |
| | | // æ¶é´æ³ |
| | | std::optional<std::chrono::system_clock::time_point> m_tQueued; |
| | | std::optional<std::chrono::system_clock::time_point> m_tStart; |
| | | std::optional<std::chrono::system_clock::time_point> m_tEnd; |
| | | |
| | | // 约æï¼å¯æä½ 们åè®®è°æ´ï¼ |
| | | static constexpr size_t MAX_ID_LEN = 64; // PJID/ CJID/ CarrierID/ MID/ PPID |
| | | static constexpr size_t MAX_PARAM_K = 32; // åæ°å |
| | | static constexpr size_t MAX_PARAM_V = 64; // åæ°å¼ |
| | | |
| | | // é误å表 |
| | | std::vector<ValidationIssue> m_issues; |
| | | }; |
| | | } |
| | | |
| | | |
| | |
| | | <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| | | <SDLCheck>true</SDLCheck> |
| | | <AdditionalIncludeDirectories>.;..;..\DatabaseSDK\include;..\MELSECSDK\include;.\CCLinkPerformance;.\GridControl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
| | | <LanguageStandard>stdcpp17</LanguageStandard> |
| | | </ClCompile> |
| | | <Link> |
| | | <SubSystem>Windows</SubSystem> |
| | |
| | | <ClInclude Include="PageRobotCmd.h" /> |
| | | <ClInclude Include="PageTransferLog.h" /> |
| | | <ClInclude Include="PortConfigurationDlg.h" /> |
| | | <ClInclude Include="ProcessJob.h" /> |
| | | <ClInclude Include="ProductionLogManager.h" /> |
| | | <ClInclude Include="RecipeDeviceBindDlg.h" /> |
| | | <ClInclude Include="RecipeManager.h" /> |
| | |
| | | <ClCompile Include="PageRobotCmd.cpp" /> |
| | | <ClCompile Include="PageTransferLog.cpp" /> |
| | | <ClCompile Include="PortConfigurationDlg.cpp" /> |
| | | <ClCompile Include="ProcessJob.cpp" /> |
| | | <ClCompile Include="ProductionLogManager.cpp" /> |
| | | <ClCompile Include="RecipeDeviceBindDlg.cpp" /> |
| | | <ClCompile Include="RecipeManager.cpp" /> |
| | |
| | | <ClCompile Include="CPageVarialbles.cpp" /> |
| | | <ClCompile Include="CPageReport.cpp" /> |
| | | <ClCompile Include="CPageCollectionEvent.cpp" /> |
| | | <ClCompile Include="ProcessJob.cpp" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClInclude Include="AlarmManager.h" /> |
| | |
| | | <ClInclude Include="CPageVarialbles.h" /> |
| | | <ClInclude Include="CPageReport.h" /> |
| | | <ClInclude Include="CPageCollectionEvent.h" /> |
| | | <ClInclude Include="ProcessJob.h" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="Servo.rc" /> |