chenluhua1980
2025-12-10 db9d120efcfe76bb73df089dca8986eca9ee0e6f
1.扫码上报,但未在配置中设置变量;
已修改3个文件
117 ■■■■■ 文件已修改
SourceCode/Bond/Servo/HsmsPassive.cpp 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/HsmsPassive.h 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.cpp 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/HsmsPassive.cpp
@@ -1924,5 +1924,10 @@
    return requestEventReportSend("Panel_End");
}
int CHsmsPassive::requestEventReportSend_OCR_PanelID_Read_OK()
{
    return requestEventReportSend("OCR_PanelID_Read_OK");
}
SourceCode/Bond/Servo/HsmsPassive.h
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include <string>
#include <list>
#include "HsmsAction.h"
@@ -39,7 +39,7 @@
#define CAACK_6                    6        /* command performed with errors */
/*
 * 常量数据结构
 * 常量数据结构
 */
typedef struct _EQConstant
{
@@ -48,7 +48,7 @@
} EQConstant;
/*
 * Command 数据结构
 * Command 数据结构
 */
typedef struct _CommandParameter
{
@@ -57,7 +57,7 @@
} CommandParameter;
/*
 * Report 数据结构
 * Report 数据结构
 */
typedef struct _REPORT
{
@@ -66,7 +66,7 @@
} REPORT;
/*
 * Value 数据结构
 * Value 数据结构
 */
typedef struct _VALUE
{
@@ -115,62 +115,62 @@
    ~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();
    // 从文件中加载CVariable列表
    // 从文件中加载CVariable列表
    int loadVarialbles(const char* pszFilepath);
    // 取得CVariable列表
    // 取得CVariable列表
    std::vector<SERVO::CVariable*>& getVariables();
    // 取得指定Variable
    // 取得指定Variable
    SERVO::CVariable* getVariable(int variableId);
    SERVO::CVariable* getVariable(const char* pszName);
    // 设置变量值
    // 设置变量值
    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);
    // 从文件中加载CReport列表
    // 从文件中加载CReport列表
    int loadReports(const char* pszFilepath);
    // 取得Report列表
    // 取得Report列表
    std::vector<SERVO::CReport*>& getReports();
    // 从文件中加载CCollectionEvent列表
    // 从文件中加载CCollectionEvent列表
    int loadCollectionEvents(const char* pszFilepath);
    // 取得CCollectionEvent列表
    // 取得CCollectionEvent列表
    std::vector<SERVO::CCollectionEvent*>& getCollectionEvents();
    // 取消/删除所有CollectionEvent
    // 取消/删除所有CollectionEvent
    void clearAllCollectionEvent();
    // 取得CCollectionEvent
    // 取得CCollectionEvent
    SERVO::CCollectionEvent* getEvent(unsigned short CEID);
    // 取得Report
    // 取得Report
    SERVO::CReport* getReport(int rptid);
    void setListener(SECSListener listener);
@@ -185,7 +185,7 @@
    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);
@@ -201,11 +201,12 @@
    int requestEventReportSend_CJ_End();
    int requestEventReportSend_Panel_Start();
    int requestEventReportSend_Panel_End();
    int requestEventReportSend_OCR_PanelID_Read_OK();
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);
SourceCode/Bond/Servo/Model.cpp
@@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "Model.h"
#include "Log.h"
#include "Common.h"
@@ -25,7 +25,7 @@
{
    if (m_pObservable == nullptr) {
        m_pObservable = RX_AllocaObservable([&](IObservableEmitter* e) -> void {
            m_pObservableEmitter = e;            // 保存发射器
            m_pObservableEmitter = e;            // 保存发射器
        });
    }
@@ -83,7 +83,7 @@
    m_configuration.setFilepath((LPTSTR)(LPCTSTR)strIniFile);
    m_configuration.getUnitId(strUnitId);
    // 机器型号和软件版本号应从配置中读取,当前先固定值
    // 机器型号和软件版本号应从配置中读取,当前先固定值
    CString strModeType = _T("Master");
    CString strSoftRev = _T("1.0.2");
@@ -108,10 +108,10 @@
    SECSListener listener;
    listener.onEQOffLine = [&](void* pFrom) -> void {
        LOGI("远程请求OffLine");
        LOGI("远程请求OffLine");
    };
    listener.onEQOnLine = [&](void* pFrom) -> void {
        LOGI("远程请求OnLine");
        LOGI("远程请求OnLine");
    };
    listener.onCommand = [&](void* pFrom, const char* pszName, std::vector<CommandParameter>& params) -> void {
        LOGI("onCommand:%s", pszName);
@@ -120,13 +120,13 @@
        }
    };
    listener.onEQConstantRequest = [&](void* pFrom, std::vector<EQConstant>& eqcs) -> void {
        // 在此填充常量值,目前仅是加1后返回
        // 在此填充常量值,目前仅是加1后返回
        for (auto& item : eqcs) {
            sprintf_s(item.szValue, 256, "Test%d", item.id + 1);
        }
    };
    listener.onEQConstantSend = [&](void* pFrom, std::vector<EQConstant>& eqcs) -> void {
        // 在此保存和设置机器常量值
        // 在此保存和设置机器常量值
        for (auto& item : eqcs) {
            LOGI("onEQConstantRequest: %d, %s", item.id, item.szValue);
        }
@@ -296,6 +296,13 @@
    };
    masterListener.onEqVcrEventReport = [&](void* pMaster, SERVO::CEquipment* pEquipment, SERVO::CVcrEventReport* pReport) {
        LOGE("<CModel>onEqVcrEventReport.");
        if (pReport != nullptr) {
            m_hsmsPassive.setVariableValue("PanelStartID", pReport->getGlassId().c_str());
            int nRet = m_hsmsPassive.requestEventReportSend_OCR_PanelID_Read_OK();
            if (nRet != ER_NOERROR) {
                LOGE("<CModel>requestEventReportSend_OCR_PanelID_Read_OK failed, ret=%d", nRet);
            }
        }
    };
    masterListener.onEqDataChanged = [&](void* pMaster, SERVO::CEquipment* pEquipment, int code) {
        LOGE("<CModel>onEqDataChanged.");
@@ -303,11 +310,11 @@
    };
    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;
@@ -319,48 +326,48 @@
            }
        }
        // 日志输出与状态处理
        // 日志输出与状态处理
        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());
@@ -369,7 +376,7 @@
        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"
        };
@@ -382,12 +389,12 @@
            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);
@@ -435,7 +442,7 @@
        m_hsmsPassive.setVariableValue("CJEndID", ((SERVO::CControlJob*)pj)->id().c_str());
        m_hsmsPassive.requestEventReportSend_CJ_End();
        // 结批,保存ControlJob
        // 结批,保存ControlJob
        // 
    };
    masterListener.onPjStart = [&](void* pMaster, void* pj) {
@@ -464,28 +471,28 @@
    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);
    // Glass数据库
    // Glass数据库
    strLogDir.Format(_T("%s\\db\\process.db"), (LPTSTR)(LPCTSTR)m_strWorkDir);
    std::string path((LPTSTR)(LPCTSTR)strLogDir);
    GlassLogDb::Init(path);