LAPTOP-SNT8I5JK\Boounion
2025-06-17 3c387cc7bcd469938fbfac8bc5435bb1e846c70f
SourceCode/Bond/Servo/Model.cpp
@@ -6,6 +6,7 @@
#include "CEqAlarmStep.h"
#include "AlarmManager.h"
#include "CGlassPool.h"
#include "TransferManager.h"
CModel::CModel()
@@ -37,6 +38,18 @@
void CModel::setWorkDir(const char* pszWorkDir)
{
   m_strWorkDir = pszWorkDir;
}
void CModel::loadPortParams()
{
   BOOL portEnable, autoChangeEnable;
   int portType, portMode, cassetteType, transferMode;
   for (int i = 0; i < 4; i++) {
      m_configuration.getPortParms(i, portEnable, portType, portMode,
         cassetteType, transferMode, autoChangeEnable);
      m_master.setPortType(i, portEnable, portType, portMode, cassetteType,
         transferMode, autoChangeEnable);
   }
}
int CModel::init()
@@ -170,6 +183,85 @@
      LOGE("<CModel>onEqDataChanged.");
      notifyPtr(RX_CODE_EQ_DATA_CHANGED, pEquipment);
   };
   masterListener.onRobotTaskEvent = [&](void* pMaster, SERVO::CRobotTask* pTask, int code) {
      if (pTask == nullptr) {
         LOGE("<CModel>onRobotTaskEvent: 空任务指针,忽略事件 code=%d", code);
         return;
      }
      // 任务描述与 ID 用于日志
      const std::string& strDesc = pTask->getDescription();
      const std::string& strClassID = pTask->getId();
      // 日志输出与状态处理
      switch (code) {
      case ROBOT_EVENT_CREATE:
         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());
         break;
      case ROBOT_EVENT_ERROR:
         LOGE("<CModel>onRobotTaskEvent: 任务错误(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str());
         pTask->error();
         break;
      case ROBOT_EVENT_ABORT:
         LOGE("<CModel>onRobotTaskEvent: 任务停止(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str());
         pTask->abort();
         break;
      default:
         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 确保线程安全
         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 data;
      data.strClassID = strClassID;
      data.strCreateTime = format_time(pTask->getCreateTime());
      data.strPickTime = format_time(pTask->getFetchoutTime());
      data.strPlaceTime = format_time(pTask->getStoredTime());
      data.strEndTime = format_time(pTask->getFinishTime());
      data.strDescription = pTask->getSimpleDescription();
      // 状态映射
      static const char* STATUS_STR[] = {
         "Unknown", "Ready", "Running", "Picking", "Placing", "Restoring", "Error", "Abort", "Completed"
      };
      auto state = pTask->getState();
      int index = static_cast<int>(state);
      if (index > 0 && index < static_cast<int>(std::size(STATUS_STR))) {
         data.strStatus = STATUS_STR[index];
      }
      else {
         data.strStatus = STATUS_STR[0];
      }
      // 写入数据库
      int nRecordId = 0;
      TransferManager::getInstance().addTransferRecord(data, nRecordId);
      notifyPtrAndInt(RX_CODE_EQ_ROBOT_TASK, pTask, nullptr, code);
      LOGI("<CModel>onRobotTaskEvent: 任务记录已保存,RecordID=%d", nRecordId);
   };
   m_master.setListener(masterListener);