#pragma once #include #include #include "HsmsAction.h" #include #include #include #include #include "CCollectionEvent.h" #include "ProcessJob.h" #include "CControlJob.h" #include "CDataVariable.h" #define EQCONSTANT_VALUE_MAX 64 #define COMMAND_NAME_MAX 64 #define COMMAND_VALUE_MAX 64 #define REPORT_NAME_MAX 64 #define VALUE_NAME_MAX 64 #define ER_NOERROR 0 #define ER_NOTSELECT -1 #define ER_BUSY -2 #define ER_PARAM_ERROR -3 #define ER_NO_EVENT -4 #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_0 0 /* ok */ #define CAACK_1 1 /* invalid command */ #define CAACK_2 2 /* cannot perform now */ #define CAACK_3 3 /* invalid data or argument */ #define CAACK_4 4 /* initiated for asynchronous completion */ #define CAACK_5 5 /* rejected - invalid state */ #define CAACK_6 6 /* command performed with errors */ /* * 常量数据结构 */ typedef struct _EQConstant { unsigned int id; char szValue[EQCONSTANT_VALUE_MAX]; } EQConstant; /* * Command 数据结构 */ typedef struct _CommandParameter { char szName[COMMAND_NAME_MAX]; char szValue[COMMAND_VALUE_MAX]; } CommandParameter; /* * Report 数据结构 */ typedef struct _REPORT { char szName[REPORT_NAME_MAX]; unsigned int id; } REPORT; /* * Value 数据结构 */ typedef struct _VALUE { char szName[VALUE_NAME_MAX]; unsigned int id; } VALUE; typedef std::function SECSEQOFFLINE; typedef std::function&)> SECSCommand; typedef std::function DATETIMESYNC; typedef std::function& ids)> EDEVENTREPORT; typedef std::function EDALARMREPORT; typedef std::function (void* pFrom)> QUERYPPIDLIST; typedef std::function CARRIERACTION; typedef std::function& pjs)> PRJOBMULTICREATE; typedef std::function CONTROLJOBCREATE; typedef std::function& ppids)> DELETEPPID; typedef struct _SECSListener { SECSEQOFFLINE onEQOffLine; SECSEQOFFLINE onEQOnLine; SECSCommand onCommand; DATETIMESYNC onDatetimeSync; EDEVENTREPORT onEnableDisableEventReport; EDALARMREPORT onEnableDisableAlarmReport; QUERYPPIDLIST onQueryPPIDList; DELETEPPID onDeletePPID; CARRIERACTION onCarrierAction; PRJOBMULTICREATE onPRJobMultiCreate; CONTROLJOBCREATE onControlJobCreate; } SECSListener; class CModel; class CHsmsPassive { public: CHsmsPassive(); ~CHsmsPassive(); public: /* 设置机器型号 最大长度 20 bytes */ void setEquipmentModelType(const char* pszMode); /* 设置软件版本号 最大长度 20 bytes */ void setSoftRev(const char* pszRev); /* 添加变量值到ISECS2Item */ void addVariableValueToItem(ISECS2Item* pParent, SERVO::CVariable* pVariable); // 连接Report void linkEventReport(unsigned int CEID, unsigned int RPTID); // 取消连接report void unlinkEventReport(unsigned int CEID); // define Report SERVO::CReport* defineReport(unsigned int RPTID, std::vector& vids); // 取消 define report bool removeReport(int rptid); int deleteReport(int rptid); int addReport(int rptid, const std::vector& vids); int updateReport(int rptid, const std::vector& vids); void clearAllReport(BOOL bSave = FALSE); // 从文件中加载CVariable列表 int loadVarialbles(const char* pszFilepath); // 从文件中加载CDataVariable列表 int loadDataVarialbles(const char* pszFilepath); // 从文件中加载Equipment Constant列表 int loadEquipmentConstants(const char* pszFilepath); // 取得CVariable列表 std::vector& getVariables(); unsigned int getMaxVariableId() const; std::vector& getDataVariables(); // 取得指定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); // 设置变量值 void setVariableValue(const char* pszName, __int64 value); void setVariableValue(const char* pszName, const char* value); void setVariableValue(const char* pszName, std::vector& vars); // 执行一段持锁的代码块,用于保证 set+send 的原子性 void withVariableLock(const std::function& fn); // 从文件中加载CReport列表 int loadReports(const char* pszFilepath); // 取得Report列表 std::vector& getReports(); unsigned int getMaxReportId() const; // 从文件中加载CCollectionEvent列表 int loadCollectionEvents(const char* pszFilepath); // 取得CCollectionEvent列表 std::vector& getCollectionEvents(); unsigned int getMaxCollectionEventId() const; // 取消/删除所有CollectionEvent void clearAllCollectionEvent(); int deleteCollectionEvent(unsigned short CEID); int addCollectionEvent(unsigned int CEID, const char* name, const char* desc, const std::vector& rptids); int updateCollectionEvent(unsigned int CEID, const char* name, const char* desc, const std::vector& rptids); // 取得CCollectionEvent SERVO::CCollectionEvent* getEvent(unsigned short CEID); // 取得Report SERVO::CReport* getReport(int rptid); void setListener(SECSListener listener); unsigned OnCimWork(); void OnTimer(UINT nTimerid); void setActionTimeout(int nSecond); int init(CModel* pModel, const char* pszName, unsigned int port); int loadCacheFromFile(const char* pszFilepath); int saveCache(); int term(); int serialize(char* pszBuffer, int nBufferSize); int unserialize(const char* pszBuffer, int nBufferSize); public: /* 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_PJ_End(); int requestEventReportSend_CJ_Start(); int requestEventReportSend_CJ_End(); int requestEventReportSend_Panel_Start(); int requestEventReportSend_Panel_End(); int requestEventReportSend_OCR_PanelID_Read_OK(); 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开头的函数为回复函数 */ 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 replyEquipmentConstantSend(IMessage* pRecv); int replyDatetime(IMessage* pRecv); int replyDefineReport(IMessage* pRecv); int replyLinkEventReport(IMessage* pRecv); int replyEanbleDisableEventReport(IMessage* pRecv); int replyCommand(IMessage* pRecv); int replyConfigureSpooling(IMessage* pRecv); int replyCarrierAction(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); private: inline void Lock() { EnterCriticalSection(&m_criticalSection); } inline void Unlock() { LeaveCriticalSection(&m_criticalSection); } int onRecvMsg(IMessage* pMessage); void clearAllVariabel(); void clearAllDataVariabel(); std::vector 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; IPassive* m_pPassive; int m_nActionTimeout; unsigned int m_nSystemByte; unsigned short m_nSessionId; BOOL m_bAreYouThereRequest; std::string m_strEquipmentModelType; std::string m_strSoftRev; CRITICAL_SECTION m_criticalSection; std::list m_listAction; std::list m_listActionSent; std::list m_listActionSpooling; 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; unsigned m_nCimWorkThrdaddr; std::string m_strCacheFilepath; CHsmsAction* m_pActiveAction; private: // CVariable vector std::vector m_variabels; // CDataVariable vector std::vector m_dataVariabels; // Equipment constants struct EquipmentConstantEntry { unsigned int id{ 0 }; std::string name; std::string format; std::string remark; std::string value; }; std::vector m_equipmentConstants; // CReport vector std::vector m_reports; // CollectionEvent vector std::vector m_collectionEvents; // 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> m_spoolBlacklistByStream; bool m_spoolingEnabled{ true }; private: bool shouldSpool(uint8_t streamId, uint8_t functionId) const; };