1.完善警告信息,打通CC-Link获取警告信息到通过SECS上报警告信息的路径。
| | |
| | | #include "stdafx.h" |
| | | #include "AlarmManager.h" |
| | | #include <sstream> |
| | | #include <fstream> |
| | | #include <iostream> |
| | | #include <stdexcept> |
| | | #include <ctime> |
| | | #include <iomanip> |
| | | #include <random> |
| | | |
| | | // 常量 |
| | | const std::string DATABASE_FILE = R"(AlarmManager.db)"; |
| | |
| | | throw std::runtime_error("Failed to connect to database."); |
| | | } |
| | | |
| | | const std::string createTableQuery = R"( |
| | | CREATE TABLE IF NOT EXISTS alarms ( |
| | | id TEXT NOT NULL, |
| | | device_name TEXT NOT NULL, |
| | | description TEXT NOT NULL, |
| | | start_time DATETIME NOT NULL, |
| | | end_time DATETIME NOT NULL |
| | | // 创建设备表 |
| | | const std::string createDevicesTableQuery = R"( |
| | | CREATE TABLE IF NOT EXISTS devices ( |
| | | device_id TEXT PRIMARY KEY NOT NULL, |
| | | device_name TEXT NOT NULL |
| | | ) |
| | | )"; |
| | | if (!m_pDB->executeQuery(createDevicesTableQuery)) { |
| | | return false; |
| | | } |
| | | |
| | | return m_pDB->executeQuery(createTableQuery); |
| | | // 创建单元表,设备ID和单元ID组合作为主键 |
| | | const std::string createUnitsTableQuery = R"( |
| | | CREATE TABLE IF NOT EXISTS units ( |
| | | device_id TEXT NOT NULL, |
| | | unit_id TEXT NOT NULL, |
| | | unit_name TEXT NOT NULL, |
| | | PRIMARY KEY (device_id, unit_id), |
| | | FOREIGN KEY (device_id) REFERENCES devices(device_id) |
| | | ) |
| | | )"; |
| | | if (!m_pDB->executeQuery(createUnitsTableQuery)) { |
| | | return false; |
| | | } |
| | | |
| | | // 创建报警表,报警记录的alarm_event_id是主键 |
| | | const std::string createAlarmsTableQuery = R"( |
| | | CREATE TABLE IF NOT EXISTS alarms ( |
| | | alarm_event_id INTEGER PRIMARY KEY AUTOINCREMENT, |
| | | id TEXT NOT NULL, |
| | | device_id TEXT NOT NULL, |
| | | unit_id TEXT NOT NULL, |
| | | description TEXT NOT NULL, |
| | | start_time DATETIME NOT NULL, |
| | | end_time DATETIME NOT NULL, |
| | | FOREIGN KEY (device_id) REFERENCES devices(device_id), |
| | | FOREIGN KEY (unit_id) REFERENCES units(unit_id) |
| | | ) |
| | | )"; |
| | | return m_pDB->executeQuery(createAlarmsTableQuery); |
| | | } |
| | | |
| | | // 销毁报警表 |
| | |
| | | } |
| | | const std::string dropTableQuery = "DROP TABLE IF EXISTS alarms"; |
| | | return m_pDB->executeQuery(dropTableQuery); |
| | | } |
| | | |
| | | // 插入模拟数据 |
| | | void AlarmManager::insertMockData() { |
| | | // 插入设备数据 |
| | | for (int i = 1; i <= 3; ++i) { |
| | | std::string deviceName = "Device" + std::to_string(i); |
| | | std::stringstream query; |
| | | query << "INSERT INTO devices (device_id, device_name) VALUES (" << i << ", '" << deviceName << "');"; |
| | | if (!m_pDB->executeQuery(query.str())) { |
| | | std::cerr << "Failed to insert device: " << i << std::endl; |
| | | } |
| | | } |
| | | |
| | | // 插入单元数据 |
| | | for (int i = 1; i <= 3; ++i) { |
| | | for (int j = 1; j <= 3; ++j) { |
| | | int unitId = (i - 1) * 3 + j; |
| | | std::string unitName = "Unit" + std::to_string(j); |
| | | std::stringstream query; |
| | | query << "INSERT INTO units (device_id, unit_id, unit_name) VALUES (" << i << "', " << unitId << ", '" << unitName << ");"; |
| | | if (!m_pDB->executeQuery(query.str())) { |
| | | std::cerr << "Failed to insert unit: " << unitId << std::endl; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 初始化随机数生成器 |
| | | std::random_device rd; |
| | | std::mt19937 gen(rd()); |
| | | std::uniform_int_distribution<> deviceDis(1, 3); |
| | | std::uniform_int_distribution<> unitDis(1, 9); |
| | | std::uniform_int_distribution<> errorCodeDis(1, 3); |
| | | std::vector<std::string> descriptions = { "Overheat", "Sensor failure", "Power outage" }; |
| | | |
| | | // 时间相关 |
| | | auto now = std::chrono::system_clock::now(); |
| | | auto start_time = std::chrono::system_clock::to_time_t(now); |
| | | auto end_time = std::chrono::system_clock::to_time_t(now + std::chrono::minutes(10)); |
| | | |
| | | std::tm start_tm = {}; |
| | | std::tm end_tm = {}; |
| | | localtime_s(&start_tm, &start_time); |
| | | localtime_s(&end_tm, &end_time); |
| | | |
| | | // 插入模拟数据 |
| | | for (int i = 0; i < 10; ++i) { |
| | | int deviceId = deviceDis(gen); // 随机设备ID |
| | | int unitId = unitDis(gen); // 随机单元ID |
| | | int errorCode = errorCodeDis(gen); // 随机错误码 |
| | | std::string description = descriptions[errorCodeDis(gen) % descriptions.size()]; // 随机报警描述 |
| | | |
| | | std::stringstream query; |
| | | query << "INSERT INTO alarms (id, device_id, unit_id, description, start_time, end_time) " |
| | | << "VALUES (" << errorCode << ", " << deviceId << ", " << unitId << ", '" << description << "', " |
| | | << "'" << std::put_time(&start_tm, "%Y-%m-%d %H:%M:%S") << "', " |
| | | << "'" << std::put_time(&end_tm, "%Y-%m-%d %H:%M:%S") << "');"; |
| | | |
| | | if (!m_pDB->executeQuery(query.str())) { |
| | | std::cerr << "Failed to insert alarm data." << std::endl; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 添加报警 |
| | |
| | | } |
| | | m_pDB->executeQuery(query.str()); |
| | | } |
| | | |
| | | // 读取报警文件 |
| | | bool AlarmManager::readAlarmFile(const std::string& filename) { |
| | | std::ifstream file(filename); |
| | | std::string line; |
| | | bool first_line = true; |
| | | |
| | | if (!file.is_open()) { |
| | | std::cerr << "Error opening file!" << std::endl; |
| | | return false; |
| | | } |
| | | |
| | | while (std::getline(file, line)) { |
| | | if (first_line) { |
| | | first_line = false; |
| | | continue; |
| | | } |
| | | |
| | | std::stringstream ss(line); |
| | | std::string cell; |
| | | AlarmInfo alarm; |
| | | |
| | | std::getline(ss, cell, ','); |
| | | std::getline(ss, alarm.strUnitID, ','); |
| | | std::getline(ss, alarm.strUnitNo, ','); |
| | | std::getline(ss, cell, ','); |
| | | alarm.nAlarmLevel = 0;// std::stoi(cell); |
| | | std::getline(ss, cell, ','); |
| | | alarm.nAlarmCode = std::stoi(cell); |
| | | std::getline(ss, cell, ','); |
| | | alarm.nAlarmID = std::stoi(cell); |
| | | std::getline(ss, alarm.strAlarmText, ','); |
| | | std::getline(ss, alarm.strDescription, ','); |
| | | |
| | | if (m_mapAlarm.find(alarm.nAlarmID) == m_mapAlarm.end()) { |
| | | m_mapAlarm[alarm.nAlarmID] = alarm; |
| | | } |
| | | else { |
| | | std::cerr << "Duplicate AlarmID: " << alarm.nAlarmID << std::endl; |
| | | } |
| | | } |
| | | |
| | | file.close(); |
| | | return true; |
| | | } |
| | | |
| | | // 将报警数据保存到文件 |
| | | bool AlarmManager::saveAlarmFile(const std::string& filename) { |
| | | std::ofstream file(filename); |
| | | |
| | | if (!file.is_open()) { |
| | | std::cerr << "打开文件写入失败!" << std::endl; |
| | | return false; |
| | | } |
| | | |
| | | // 写入标题行 |
| | | file << "No,UNIT ID,UNIT NO,Alarm Level,Alarm Code,AlarmID,Alarm Text,Description\n"; |
| | | |
| | | // 写入报警数据 |
| | | int nIndex = 1; |
| | | for (const auto& pair : m_mapAlarm) { |
| | | const AlarmInfo& alarm = pair.second; |
| | | file << nIndex++ << "," |
| | | << alarm.strUnitID << "," |
| | | << alarm.strUnitNo << "," |
| | | << alarm.nAlarmLevel << "," |
| | | << alarm.nAlarmCode << "," |
| | | << alarm.nAlarmID << "," |
| | | << alarm.strAlarmText << "," |
| | | << alarm.strDescription << "\n"; |
| | | } |
| | | |
| | | file.close(); |
| | | return true; |
| | | } |
| | | |
| | | // 通过 AlarmID 查询对应的报警信息 |
| | | const AlarmInfo* AlarmManager::getAlarmInfoByID(int nAlarmID) const { |
| | | auto it = m_mapAlarm.find(nAlarmID); |
| | | if (it != m_mapAlarm.end()) { |
| | | return &(it->second); |
| | | } |
| | | else { |
| | | std::cerr << "未找到 AlarmID: " << nAlarmID << std::endl; |
| | | return nullptr; |
| | | } |
| | | } |
| | | |
| | | // 通过多个 AlarmID 查询对应的报警信息 |
| | | std::vector<AlarmInfo> AlarmManager::getAlarmsInfoByIDs(const std::vector<int>& alarmIDs) const { |
| | | std::vector<AlarmInfo> alarms; |
| | | |
| | | for (int alarmID : alarmIDs) { |
| | | auto it = m_mapAlarm.find(alarmID); |
| | | if (it != m_mapAlarm.end()) { |
| | | alarms.push_back(it->second); |
| | | } |
| | | else { |
| | | std::cerr << "未找到 AlarmID: " << alarmID << std::endl; |
| | | } |
| | | } |
| | | |
| | | return alarms; |
| | | } |
| | |
| | | #include <string> |
| | | #include <vector> |
| | | #include <mutex> |
| | | #include <unordered_map> |
| | | #include "Database.h" |
| | | |
| | | struct AlarmInfo { |
| | | std::string strUnitID; |
| | | std::string strUnitNo; |
| | | int nAlarmLevel; |
| | | int nAlarmCode; |
| | | int nAlarmID; |
| | | std::string strAlarmText; |
| | | std::string strDescription; |
| | | }; |
| | | |
| | | using AlarmMap = std::unordered_map<int, AlarmInfo>; |
| | | |
| | | class AlarmManager { |
| | | public: |
| | |
| | | * @return 成功返回true,失败返回false |
| | | */ |
| | | bool destroyAlarmTable(); |
| | | |
| | | /** |
| | | * 插入模拟数据 |
| | | */ |
| | | void insertMockData(); |
| | | |
| | | /** |
| | | * 添加报警 |
| | |
| | | */ |
| | | void cleanOldAlarms(int daysToKeep = 30, const std::string& deviceName = ""); |
| | | |
| | | /** |
| | | * 读取报警文件 |
| | | * @param filename 文件名 |
| | | * @return 成功返回true,失败返回false |
| | | */ |
| | | bool readAlarmFile(const std::string& filename); |
| | | |
| | | /** |
| | | * 保存报警文件 |
| | | * @param filename 文件名 |
| | | * @return 成功返回true,失败返回false |
| | | */ |
| | | bool saveAlarmFile(const std::string& filename); |
| | | |
| | | /** |
| | | * 通过报警ID查询报警信息 |
| | | * @param nAlarmID 报警ID |
| | | * @return 报警信息的指针 |
| | | */ |
| | | const AlarmInfo* getAlarmInfoByID(int nAlarmID) const; |
| | | |
| | | /** |
| | | * 通过多个报警ID查询对应的报警信息 |
| | | * @param alarmIDs 多个报警ID |
| | | * @return 返回多个报警信息 |
| | | */ |
| | | std::vector<AlarmInfo> getAlarmsInfoByIDs(const std::vector<int>& alarmIDs) const; |
| | | |
| | | private: |
| | | AlarmManager(); |
| | | ~AlarmManager(); |
| | |
| | | AlarmManager& operator=(const AlarmManager&) = delete; |
| | | |
| | | BL::Database* m_pDB; |
| | | AlarmMap m_mapAlarm; |
| | | static std::mutex m_mutex; |
| | | }; |
| | | |
| | |
| | | { |
| | | |
| | | } |
| | | |
| | | int CEqAlarmStep::onReadData() |
| | | { |
| | | CStep::onReadData(); |
| | |
| | | m_nAlarmDev = nDev; |
| | | } |
| | | |
| | | int CEqAlarmStep::getAlarmState() |
| | | { |
| | | return m_nAlarmState; |
| | | } |
| | | |
| | | int CEqAlarmStep::getUnitId() |
| | | { |
| | | return m_nUnitId; |
| | | } |
| | | |
| | | int CEqAlarmStep::getAlarmLevel() |
| | | { |
| | | return m_nAlarmLevel; |
| | | } |
| | | |
| | | int CEqAlarmStep::getAlarmCode() |
| | | { |
| | | return m_nAlarmCode; |
| | | } |
| | | |
| | | int CEqAlarmStep::getAlarmId() |
| | | { |
| | | return m_nAlarmId; |
| | | } |
| | | } |
| | |
| | | virtual int onComplete(); |
| | | virtual int onTimeout(); |
| | | void setAlarmDev(int nDev); |
| | | int getAlarmState(); |
| | | int getUnitId(); |
| | | int getAlarmLevel(); |
| | | int getAlarmCode(); |
| | | int getAlarmId(); |
| | | |
| | | private: |
| | | int m_nAlarmDev; |
| | |
| | | m_nModeDev = nDev; |
| | | } |
| | | |
| | | int CEqModeStep::getMode() |
| | | { |
| | | return m_nMode; |
| | | } |
| | | |
| | | /* |
| | | 0: No Equipment Mode exist |
| | | 1: Normal Mode |
| | |
| | | virtual int onComplete(); |
| | | virtual int onTimeout(); |
| | | void setModeDev(int nDev); |
| | | int getMode(); |
| | | std::string& getModeDescription(std::string& strDescription); |
| | | |
| | | private: |
| | |
| | | |
| | | } |
| | | |
| | | int CEqStatusStep::getStatus(unsigned int uint) |
| | | { |
| | | if (uint < STATUS_MAX) { |
| | | return m_nStatus[uint]; |
| | | } |
| | | |
| | | return -1; |
| | | } |
| | | int CEqStatusStep::onReadData() |
| | | { |
| | | CStep::onReadData(); |
| | |
| | | virtual int onComplete(); |
| | | virtual int onTimeout(); |
| | | void setStatusDev(int nDev); |
| | | int getStatus(unsigned int uint); |
| | | std::string& getStatusDescription(unsigned int unid, std::string& strDescription); |
| | | |
| | | private: |
| | |
| | | m_bAutoRecipeChange = FALSE; |
| | | m_bVCREnable[0] = FALSE; |
| | | m_pCclink = nullptr; |
| | | m_nBaseAlarmId = 0; |
| | | InitializeCriticalSection(&m_criticalSection); |
| | | } |
| | | |
| | |
| | | m_pCclink = pCcLink; |
| | | } |
| | | |
| | | void CEquipment::setBaseAlarmId(int nBaseId) |
| | | { |
| | | m_nBaseAlarmId = nBaseId; |
| | | } |
| | | |
| | | int CEquipment::getBaseAlarmId() |
| | | { |
| | | return m_nBaseAlarmId; |
| | | } |
| | | |
| | | void CEquipment::getProperties(std::vector<std::pair<std::string, std::string>>& container) |
| | | { |
| | | container.clear(); |
| | |
| | | virtual const char* getClassName() = 0; |
| | | virtual void setListener(EquipmentListener listener); |
| | | void setCcLink(CCCLinkIEControl* pCcLink); |
| | | void setBaseAlarmId(int nBaseId); |
| | | int getBaseAlarmId(); |
| | | void setID(int nID); |
| | | int getID(); |
| | | void setName(const char* pszName); |
| | |
| | | private: |
| | | CCCLinkIEControl* m_pCclink; |
| | | std::map<unsigned int, CStep*> m_mapStep; |
| | | int m_nBaseAlarmId; |
| | | }; |
| | | } |
| | | |
| | |
| | | listener.onEvent = [&](void* pStep, int code, void* pData) -> void { |
| | | TRACE("<CEquipment>onEvent<%d, 0x%x>.\n", code, pData); |
| | | if (m_listener.onEqStepEvent != nullptr) { |
| | | m_listener.onEqStepEvent(this, (CStep*)pStep, code, pData); |
| | | m_listener.onEqStepEvent((CStep*)pStep, code, pData); |
| | | } |
| | | }; |
| | | |
| | |
| | | { |
| | | CEFEM* pEquipment = new CEFEM(); |
| | | pEquipment->setID(EQ_ID_EFEM); |
| | | pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); |
| | | pEquipment->setName("EFEM(ROBOT)"); |
| | | pEquipment->setDescription("EFEM(ROBOT)."); |
| | | pEquipment->setReadBitBlock(0x4000, 0x45ff); |
| | |
| | | // 添加 step |
| | | { |
| | | CEqModeStep* pStep = new CEqModeStep(); |
| | | pStep->setName("EQMode"); |
| | | pStep->setName(STEP_MODE); |
| | | pStep->setListener(listener); |
| | | pStep->setWriteSignalDev(0x30); |
| | | pStep->setModeDev(0x4a8c); |
| | |
| | | } |
| | | { |
| | | CEqStatusStep* pStep = new CEqStatusStep(); |
| | | pStep->setName("EQStatus"); |
| | | pStep->setName(STEP_STATUS); |
| | | pStep->setListener(listener); |
| | | pStep->setWriteSignalDev(0x31); |
| | | pStep->setStatusDev(0x4a68); |
| | |
| | | } |
| | | { |
| | | CEqAlarmStep* pStep = new CEqAlarmStep(); |
| | | pStep->setName("EQAlarm1"); |
| | | pStep->setName(STEP_ALARM_BLOCK1); |
| | | pStep->setListener(listener); |
| | | pStep->setWriteSignalDev(0x32); |
| | | pStep->setAlarmDev(0x4c1d); |
| | |
| | | } |
| | | { |
| | | CEqAlarmStep* pStep = new CEqAlarmStep(); |
| | | pStep->setName("EQAlarm2"); |
| | | pStep->setName(STEP_ALARM_BLOCK2); |
| | | pStep->setListener(listener); |
| | | pStep->setWriteSignalDev(0x33); |
| | | pStep->setAlarmDev(0x4c4a); |
| | |
| | | } |
| | | { |
| | | CEqAlarmStep* pStep = new CEqAlarmStep(); |
| | | pStep->setName("EQAlarm3"); |
| | | pStep->setName(STEP_ALARM_BLOCK3); |
| | | pStep->setListener(listener); |
| | | pStep->setWriteSignalDev(0x34); |
| | | pStep->setAlarmDev(0x4c77); |
| | |
| | | } |
| | | { |
| | | CEqAlarmStep* pStep = new CEqAlarmStep(); |
| | | pStep->setName("EQAlarm4"); |
| | | pStep->setName(STEP_ALARM_BLOCK4); |
| | | pStep->setListener(listener); |
| | | pStep->setWriteSignalDev(0x35); |
| | | pStep->setAlarmDev(0x4ca4); |
| | |
| | | } |
| | | { |
| | | CEqAlarmStep* pStep = new CEqAlarmStep(); |
| | | pStep->setName("EQAlarm5"); |
| | | pStep->setName(STEP_ALARM_BLOCK5); |
| | | pStep->setListener(listener); |
| | | pStep->setWriteSignalDev(0x36); |
| | | pStep->setAlarmDev(0x4cd1); |
| | |
| | | |
| | | namespace SERVO { |
| | | typedef std::function<void(void* pMaster, CEquipment* pEiuipment, BOOL bAlive)> ONEQALIVE; |
| | | typedef std::function<void(void* pEiuipment, CStep* pStep, int code, void* pData)> ONEQSTEPEVENT; |
| | | typedef std::function<void(CStep* pStep, int code, void* pData)> ONEQSTEPEVENT; |
| | | typedef struct _MasterListener |
| | | { |
| | | ONEQALIVE onEqAlive; |
| | |
| | | #define RX_CODE_MES_MESSAGE 1002 |
| | | #define RX_HSMS_TERMINAL_TEXT 1003 |
| | | #define RX_CODE_EQ_ALIVE 1004 |
| | | |
| | | #define RX_CODE_STEP_EVENT_READDATA 1005 |
| | | |
| | | /* Channel Name */ |
| | | #define MC_CHANNEL1_NAME "McChannel1" |
| | |
| | | #define BTN_LOG_BKGND_HOVER RGB(153, 217, 234) |
| | | #define BTN_LOG_BKGND_PRESS RGB(133, 203, 225) |
| | | |
| | | /* ALARM BTN */ |
| | | #define BTN_ALARM_FRAME_NORMAL RGB(88, 88, 88) |
| | | #define BTN_ALARM_FRAME_HOVER RGB(88, 88, 88) |
| | | #define BTN_ALARM_FRAME_PRESS RGB(88, 88, 88) |
| | | #define BTN_ALARM_BKGND_NORMAL RGB(232, 232, 232) |
| | | #define BTN_ALARM_BKGND_HOVER RGB(153, 217, 234) |
| | | #define BTN_ALARM_BKGND_PRESS RGB(133, 203, 225) |
| | | |
| | | /* Equipment ID */ |
| | | #define EQ_ID_EFEM 1 |
| | | #define EQ_ID_Bonder1 2 |
| | | #define EQ_ID_Bonder2 3 |
| | | |
| | | |
| | | /* step name */ |
| | | #define STEP_MODE _T("EQMode") |
| | | #define STEP_STATUS _T("EQStatus") |
| | | #define STEP_ALARM_START _T("EQAlarm") |
| | | #define STEP_ALARM_BLOCK1 _T("EQAlarm1") |
| | | #define STEP_ALARM_BLOCK2 _T("EQAlarm2") |
| | | #define STEP_ALARM_BLOCK3 _T("EQAlarm3") |
| | | #define STEP_ALARM_BLOCK4 _T("EQAlarm4") |
| | | #define STEP_ALARM_BLOCK5 _T("EQAlarm5") |
| | | |
| | | |
| | | #define BASE_ALARM_EFEM 10000 |
| | | #define BASE_ALARM_BONDER1 20000 |
| | | #define BASE_ALARM_BONDER2 30000 |
| | |
| | | #include "Model.h" |
| | | #include "Log.h" |
| | | #include "Common.h" |
| | | #include "ToolUnits.h" |
| | | #include "CEqAlarmStep.h" |
| | | #include "AlarmManager.h" |
| | | |
| | | |
| | | CModel::CModel() |
| | |
| | | masterListener.onEqCimStateChanged = [&](void* pMaster, SERVO::CEquipment* pEquipment, BOOL bOn) -> void { |
| | | LOGI("<CModel>Equipment Cim State:%s(%s).\n", pEquipment->getName().c_str(), |
| | | bOn ? _T("ON") : _T("OFF")); |
| | | notifyPtr(RX_CODE_EQ_ALIVE, pEquipment); |
| | | |
| | | }; |
| | | masterListener.onEqStepEvent = [&](void* pEquipment, SERVO::CStep* pStep, int code, void* pData) -> void { |
| | | SERVO::CEquipment* p = (SERVO::CEquipment*)pEquipment; |
| | | masterListener.onEqStepEvent = [&](SERVO::CStep* pStep, int code, void* pData) -> void { |
| | | if (code == STEP_EVENT_READDATA) { |
| | | LOGI("<CModel>onEqStepEvent,数据变化:%s(%s, 0x%x).\n", pStep->getEquipment()->getName().c_str(), |
| | | pStep->getName().c_str(), pData); |
| | | notifyPtr(RX_CODE_STEP_EVENT_READDATA, pStep); |
| | | |
| | | // 处理警告信息 |
| | | if (isAlarmStep(pStep)) { |
| | | // 保存到数据库 |
| | | AlarmManager& alarmManager = AlarmManager::getInstance(); |
| | | std::string strAlarmText; |
| | | SERVO::CEquipment* pEquipment = pStep->getEquipment(); |
| | | SERVO::CEqAlarmStep* pEqAlarmStep = (SERVO::CEqAlarmStep*)pStep; |
| | | const AlarmInfo* pAlarmInfo = alarmManager.getAlarmInfoByID(pEqAlarmStep->getAlarmId()); |
| | | if (pAlarmInfo != nullptr) { |
| | | strAlarmText = pAlarmInfo->strAlarmText; |
| | | } |
| | | int state = pEqAlarmStep->getAlarmState(); |
| | | if (state == 1) { |
| | | LOGE("<CAlarmDlg> 发生警告"); |
| | | std::string startTime = CToolUnits::timeToString2(CToolUnits::getTimestamp()); |
| | | std::string endTime = ""; |
| | | bool result = alarmManager.addAlarm(std::to_string(pEqAlarmStep->getAlarmId()), |
| | | pEquipment->getName(), strAlarmText, startTime, endTime); |
| | | if (result) { |
| | | LOGI("<CAlarmDlg> Alarm added successfully!"); |
| | | } |
| | | else { |
| | | LOGE("<CAlarmDlg> Failed to add alarm."); |
| | | } |
| | | } |
| | | else { |
| | | LOGE("<CAlarmDlg> i消除警告"); |
| | | //alarmManager.updateAlarmEndTime(std::to_string(pEqAlarmStep->getAlarmId()), |
| | | // pEquipment->getName()); |
| | | } |
| | | |
| | | m_hsmsPassive.requestAlarmReport(pEqAlarmStep->getAlarmState(), |
| | | pEquipment->getBaseAlarmId() + pEqAlarmStep->getAlarmId(), |
| | | strAlarmText.c_str()); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | m_master.setListener(masterListener); |
| | | |
| | | |
| | | // 加载警告信息 |
| | | AlarmManager& alarmManager = AlarmManager::getInstance(); |
| | | char szBuffer[MAX_PATH]; |
| | | sprintf_s(szBuffer, MAX_PATH, "%s\\AlarmList.csv", (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | alarmManager.readAlarmFile(szBuffer); |
| | | |
| | | |
| | | |
| | | return 0; |
| | | } |
| | |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | bool CModel::isAlarmStep(SERVO::CStep* pStep) |
| | | { |
| | | return CToolUnits::startsWith(pStep->getName(), STEP_ALARM_START); |
| | | } |
| | |
| | | void setWorkDir(const char* pszWorkDir); |
| | | int init(); |
| | | int term(); |
| | | bool isAlarmStep(SERVO::CStep* pStep); |
| | | |
| | | public: |
| | | int notify(int code); |
| | |
| | | return false; |
| | | } |
| | | |
| | | // 删除指定表的所有数据 |
| | | int SECSRuntimeManager::deleteAllDataFromTable(const std::string& tableName) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return 1; |
| | | } |
| | | |
| | | // 构建删除所有数据的 SQL 语句 |
| | | std::string deleteSQL = "DELETE FROM " + tableName + ";"; |
| | | if (!m_pDB->executeQuery(deleteSQL)) { |
| | | return 2; |
| | | } |
| | | |
| | | return 0; // 删除成功,返回 0 表示操作成功完成。 |
| | | } |
| | | |
| | | // 查询指定表所有数据 |
| | | bool SECSRuntimeManager::getAllDataFromTable(const std::string& tableName, std::vector<std::vector<std::string>>& outData) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return false; // 数据库连接失败 |
| | | } |
| | | |
| | | // 查询 SQL 语句,获取指定表的所有数据 |
| | | std::string querySQL = "SELECT * FROM " + tableName + ";"; |
| | | outData = m_pDB->fetchResults(querySQL); // 使用输出参数赋值结果 |
| | | |
| | | return true; // 查询成功 |
| | | } |
| | | |
| | | // 删除指定表中指定 ID 的数据 |
| | | int SECSRuntimeManager::deleteDataByID(const std::string& tableName, int nID) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return 1; // 数据库未连接,返回 1 |
| | | } |
| | | |
| | | // 检查 ID 是否存在 |
| | | if (!isIDDuplicate(nID)) { |
| | | return 2; // ID 不存在,返回 2 |
| | | } |
| | | |
| | | // 构建删除 SQL 语句 |
| | | std::string deleteSQL = "DELETE FROM " + tableName + " WHERE ID = " + std::to_string(nID) + ";"; |
| | | if (!m_pDB->executeQuery(deleteSQL)) { |
| | | return 3; // 删除失败,返回 3 |
| | | } |
| | | |
| | | return 0; // 删除成功,返回 0 |
| | | } |
| | | |
| | | // 设置数据库连接 |
| | | void SECSRuntimeManager::setDatabase(BL::Database* db) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | |
| | | } |
| | | } |
| | | |
| | | // 初始化 SystemSV 表 |
| | | void SECSRuntimeManager::initSystemSVTable() { |
| | | // 初始化指定的 SystemV 表 |
| | | void SECSRuntimeManager::initSystemVTable(const std::string& tableName) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | throw std::runtime_error("Database not connected."); |
| | | } |
| | | |
| | | // 创建 SystemSV 表(如果不存在) |
| | | // 创建表的 SQL 语句 |
| | | std::string createTableSQL = |
| | | "CREATE TABLE IF NOT EXISTS SystemSV (" |
| | | "CREATE TABLE IF NOT EXISTS " + tableName + " (" |
| | | "ID INTEGER PRIMARY KEY, " |
| | | "Name TEXT UNIQUE NOT NULL, " |
| | | "DataType TEXT NOT NULL, " |
| | |
| | | "Remark TEXT, " |
| | | "SystemID INTEGER);"; |
| | | |
| | | // 执行创建表操作 |
| | | if (!m_pDB->executeQuery(createTableSQL)) { |
| | | throw std::runtime_error("Failed to create SystemSV table."); |
| | | } |
| | | |
| | | // 预定义的 SV 数据 |
| | | std::vector<std::tuple<int, std::string, std::string, int, std::string, std::string, int>> svData = { |
| | | {1, "SYS_LICENSE_CODE", "ASCII", 0, "NULL", "License code (Formal; Evaluation; NoLicense)", 1}, |
| | | {2, "SYS_LICENSE_STATUS", "UINT_1", 0, "NULL", "License status(0:Unauthorized; 1:Authorized; 2:Evaluation; 3:Evaluation Expiring; 4:Trial; 5:Trial End)", 2}, |
| | | {3, "GEM_CLOCK", "ASCII", 0, "NULL", "System Clock", 3}, |
| | | {4, "SYS_SECS_COMM_MODE", "UINT_1", 0, "NULL", "SECS Communication Mode(0:HSMS Mode; 1:SECSI Mode)", 4}, |
| | | {5, "SYS_SECS_DRIVER_CONNECT_STATE", "UINT_1", 0, "NULL", "Initial SECS Driver Connect State(0:Stop; 1:Start)", 5} |
| | | }; |
| | | |
| | | for (const auto& entry : svData) { |
| | | int nID, nLength, nSystemID; |
| | | std::string sName, sDataType, sRemark, sUnit; |
| | | std::tie(nID, sName, sDataType, nLength, sUnit, sRemark, nSystemID) = entry; |
| | | |
| | | // 检查 Name 是否已存在 |
| | | int count = getIntFromDB("SELECT COUNT(*) FROM SystemSV WHERE Name = '" + sName + "';"); |
| | | if (count == 0) { |
| | | // 插入数据 |
| | | std::string insertSQL = "INSERT INTO SystemSV (ID, Name, DataType, Length, Unit, Remark, SystemID) VALUES (" |
| | | + std::to_string(nID) + ", '" |
| | | + sName + "', '" |
| | | + sDataType + "', " |
| | | + (nLength > 0 ? std::to_string(nLength) : "NULL") + ", " |
| | | + ((sUnit == "NULL") ? "NULL" : "'" + sUnit + "'") + ", '" |
| | | + sRemark + "', " |
| | | + std::to_string(nSystemID) + ");"; |
| | | |
| | | if (!m_pDB->executeQuery(insertSQL)) { |
| | | throw std::runtime_error("Failed to insert SystemSV data."); |
| | | } |
| | | } |
| | | throw std::runtime_error("Failed to create " + tableName + " table."); |
| | | } |
| | | } |
| | | |
| | | // 添加 SystemSV 数据 |
| | | int SECSRuntimeManager::addSystemSV(int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID) { |
| | | // 添加指定的 SystemV 表 |
| | | int SECSRuntimeManager::addSystemVData(const std::string& tableName, int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return 1; |
| | | return 1; // 数据库未连接 |
| | | } |
| | | |
| | | // 检查 ID 和 Name 是否重复 |
| | | if (isIDDuplicate(nID)) { |
| | | return 2; |
| | | return 2; // ID 重复 |
| | | } |
| | | |
| | | if (isNameDuplicate(sName)) { |
| | | return 3; |
| | | return 3; // Name 重复 |
| | | } |
| | | |
| | | // 如果 Unit 是 "NULL" 字符串或者为空,则插入 NULL 值 |
| | | std::string insertSQL = "INSERT INTO SystemSV (ID, Name, DataType, Length, Unit, Remark, SystemID) VALUES (" |
| | | // 构建插入语句 |
| | | std::string insertSQL = "INSERT INTO " + tableName + " (ID, Name, DataType, Length, Unit, Remark, SystemID) VALUES (" |
| | | + std::to_string(nID) + ", '" |
| | | + sName + "', '" |
| | | + sDataType + "', " |
| | |
| | | + sRemark + "', " |
| | | + std::to_string(nSystemID) + ");"; |
| | | |
| | | // 执行插入操作 |
| | | if (!m_pDB->executeQuery(insertSQL)) { |
| | | return 4; |
| | | return 4; // 插入失败 |
| | | } |
| | | |
| | | return 0; |
| | | return 0; // 插入成功 |
| | | } |
| | | |
| | | // 获取指定 ID 的 SystemSV 数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getSystemSVByID(int nID) { |
| | | // 获取指定 ID 的 SystemV 数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getSystemVByID(const std::string& tableName, int nID) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return {}; |
| | | return {}; // 如果数据库未连接,返回空结果 |
| | | } |
| | | |
| | | std::string query = "SELECT * FROM SystemSV WHERE ID = " + std::to_string(nID) + ";"; |
| | | // 构建查询 SQL 语句 |
| | | std::string query = "SELECT * FROM " + tableName + " WHERE ID = " + std::to_string(nID) + ";"; |
| | | |
| | | // 执行查询并返回结果 |
| | | return m_pDB->fetchResults(query); |
| | | } |
| | | |
| | | // 获取所有 SystemSV 数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getAllSystemSV() { |
| | | // 获取 SystemV 的所有数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getAllSystemV(const std::string& tableName) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return {}; |
| | | return {}; // 如果数据库未连接,返回空结果 |
| | | } |
| | | |
| | | std::string query = "SELECT * FROM SystemSV;"; |
| | | // 构建查询 SQL 语句 |
| | | std::string query = "SELECT * FROM " + tableName + ";"; |
| | | |
| | | // 执行查询并返回结果 |
| | | return m_pDB->fetchResults(query); |
| | | } |
| | | |
| | | // 更新指定 ID 的 SystemSV 数据 |
| | | int SECSRuntimeManager::updateIDSystemSV(int nID, int sNewID) { |
| | | // 更新 SystemV 的 ID 数据 |
| | | int SECSRuntimeManager::updateIDSystemV(const std::string& tableName, int nID, int sNewID) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return 1; |
| | |
| | | return 2; |
| | | } |
| | | |
| | | // 检查新 ID 是否重复 |
| | | if (isIDDuplicate(sNewID)) { |
| | | return 3; |
| | | } |
| | | |
| | | // 构建更新的 SQL 语句 |
| | | std::string updateSQL = "UPDATE SystemSV SET ID = " + std::to_string(sNewID) + " WHERE ID = " + std::to_string(nID) + ";"; |
| | | std::string updateSQL = "UPDATE " + tableName + " SET ID = " + std::to_string(sNewID) + " WHERE ID = " + std::to_string(nID) + ";"; |
| | | if (!m_pDB->executeQuery(updateSQL)) { |
| | | return 4; |
| | | } |
| | |
| | | return 0; |
| | | } |
| | | |
| | | // 更新所有 SystemSV 数据 |
| | | int SECSRuntimeManager::updateAllSystemSV(int nID, int sNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID) { |
| | | // 更新 SystemV 的所有字段 |
| | | int SECSRuntimeManager::updateAllSystemV(const std::string& tableName, int nID, int sNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return 1; |
| | |
| | | } |
| | | |
| | | // 构建更新的 SQL 语句 |
| | | std::string updateSQL = "UPDATE SystemSV SET "; |
| | | std::string updateSQL = "UPDATE " + tableName + " SET "; |
| | | |
| | | bool firstField = true; |
| | | |
| | |
| | | return 0; |
| | | } |
| | | |
| | | // 删除指定 ID 的 SystemSV 数据 |
| | | int SECSRuntimeManager::deleteSystemSVByID(int nID) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return 1; |
| | | } |
| | | |
| | | // 检查是否存在该 ID |
| | | if (!isIDDuplicate(nID)) { |
| | | return 2; |
| | | } |
| | | |
| | | // 构建删除的 SQL 语句 |
| | | std::string deleteSQL = "DELETE FROM SystemSV WHERE ID = " + std::to_string(nID) + ";"; |
| | | if (!m_pDB->executeQuery(deleteSQL)) { |
| | | return 3; |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int SECSRuntimeManager::deleteAllSystemSV() { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return 1; |
| | | } |
| | | |
| | | // 构建删除所有数据的 SQL 语句 |
| | | std::string deleteSQL = "DELETE FROM SystemSV;"; |
| | | if (!m_pDB->executeQuery(deleteSQL)) { |
| | | return 2; |
| | | } |
| | | |
| | | return 0; // 删除成功,返回 0 表示操作成功完成。 |
| | | } |
| | | |
| | | // 初始化 EqpSV 表 |
| | | void SECSRuntimeManager::initEqpSVTable() { |
| | | // 初始化指定的 EqpV 表 |
| | | void SECSRuntimeManager::initEqpVTable(const std::string& tableName) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | throw std::runtime_error("Database not connected."); |
| | | } |
| | | |
| | | // 创建 EqpSV 表 |
| | | // 创建设备表的 SQL 语句 |
| | | std::string createTableSQL = |
| | | "CREATE TABLE IF NOT EXISTS EqpSV (" |
| | | "CREATE TABLE IF NOT EXISTS " + tableName + " (" |
| | | "ID INTEGER PRIMARY KEY, " |
| | | "Name TEXT UNIQUE NOT NULL, " |
| | | "DataType TEXT NOT NULL, " |
| | |
| | | "SeqNo INTEGER);"; |
| | | |
| | | if (!m_pDB->executeQuery(createTableSQL)) { |
| | | throw std::runtime_error("Failed to create EqpSV table."); |
| | | throw std::runtime_error("Failed to create " + tableName + " table."); |
| | | } |
| | | } |
| | | |
| | | // 添加 EqpSV 数据 |
| | | int SECSRuntimeManager::addEqpSV(int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo) { |
| | | // 添加指定 EqpV 表的数据 |
| | | int SECSRuntimeManager::addEqpVData(const std::string& tableName, int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return 1; |
| | | } |
| | | |
| | | // 检查 ID 是否重复 |
| | | if (isIDDuplicate(nID)) { |
| | | return 2; |
| | | } |
| | | |
| | | // 检查 Name 是否重复 |
| | | if (isNameDuplicate(sName)) { |
| | | return 3; |
| | | } |
| | | |
| | | // 构建 SQL 插入语句,插入数据到 EqpSV 表中。 |
| | | std::string insertSQL = "INSERT INTO EqpSV (ID, Name, DataType, Length, Unit, Remark, SeqNo) VALUES (" |
| | | // 构建 SQL 插入语句 |
| | | std::string insertSQL = "INSERT INTO " + tableName + " (ID, Name, DataType, Length, Unit, Remark, SeqNo) VALUES (" |
| | | + std::to_string(nID) + ", '" |
| | | + sName + "', '" |
| | | + sDataType + "', " |
| | |
| | | + sRemark + "', " |
| | | + std::to_string(nSeqNo) + ");"; |
| | | |
| | | // 执行插入操作,若失败则抛出异常。 |
| | | // 执行插入操作 |
| | | if (!m_pDB->executeQuery(insertSQL)) { |
| | | return 4; |
| | | } |
| | |
| | | return 0; // 插入成功,返回 0 表示操作成功完成。 |
| | | } |
| | | |
| | | // 查找指定 ID 的 EqpSV 数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getEqpSVByID(int nID) { |
| | | // 查询指定 ID 的 EqpV 数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getEqpVDataByID(const std::string& tableName, int nID) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return {}; |
| | | } |
| | | |
| | | // 查询 SQL 语句 |
| | | std::string querySQL = "SELECT * FROM EqpSV WHERE ID = " + std::to_string(nID) + ";"; |
| | | std::string querySQL = "SELECT * FROM " + tableName + " WHERE ID = " + std::to_string(nID) + ";"; |
| | | return m_pDB->fetchResults(querySQL); // 直接返回查询结果 |
| | | } |
| | | |
| | | // 查找所有 EqpSV 数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getAllEqpSV() { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return {}; |
| | | } |
| | | |
| | | // 查询 SQL 语句,获取所有数据 |
| | | std::string querySQL = "SELECT * FROM EqpSV;"; |
| | | return m_pDB->fetchResults(querySQL); // 直接返回查询结果 |
| | | } |
| | | |
| | | // 更新指定 ID 的 EqpSV 数据 |
| | | int SECSRuntimeManager::updateEqpSV(int nID, int nNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo) { |
| | | // 更新指定的 EqpV 数据 |
| | | int SECSRuntimeManager::updateEqpV(const std::string& tableName, int nID, int nNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return 1; // 如果数据库未连接,返回 1 |
| | |
| | | } |
| | | |
| | | // 构建更新 SQL 语句 |
| | | std::string updateSQL = "UPDATE EqpSV SET "; |
| | | std::string updateSQL = "UPDATE " + tableName + " SET "; |
| | | |
| | | bool firstField = true; |
| | | |
| | |
| | | return 0; // 更新成功,返回 0 |
| | | } |
| | | |
| | | // 删除指定 ID 的 EqpSV 数据 |
| | | // 初始化 SystemSV 表 |
| | | void SECSRuntimeManager::initSystemSVTable() { |
| | | initSystemVTable("SystemSV"); |
| | | |
| | | // 预定义的 SV 数据 |
| | | std::vector<std::tuple<int, std::string, std::string, int, std::string, std::string, int>> svData = { |
| | | {1, "SYS_LICENSE_CODE", "ASCII", 0, "NULL", "License code (Formal; Evaluation; NoLicense)", 1}, |
| | | {2, "SYS_LICENSE_STATUS", "UINT_1", 0, "NULL", "License status(0:Unauthorized; 1:Authorized; 2:Evaluation; 3:Evaluation Expiring; 4:Trial; 5:Trial End)", 2}, |
| | | {3, "GEM_CLOCK", "ASCII", 0, "NULL", "System Clock", 3}, |
| | | {4, "SYS_SECS_COMM_MODE", "UINT_1", 0, "NULL", "SECS Communication Mode(0:HSMS Mode; 1:SECSI Mode)", 4}, |
| | | {5, "SYS_SECS_DRIVER_CONNECT_STATE", "UINT_1", 0, "NULL", "Initial SECS Driver Connect State(0:Stop; 1:Start)", 5} |
| | | }; |
| | | |
| | | for (const auto& entry : svData) { |
| | | int nID, nLength, nSystemID; |
| | | std::string sName, sDataType, sRemark, sUnit; |
| | | std::tie(nID, sName, sDataType, nLength, sUnit, sRemark, nSystemID) = entry; |
| | | |
| | | // 检查 Name 是否已存在 |
| | | int count = getIntFromDB("SELECT COUNT(*) FROM SystemSV WHERE Name = '" + sName + "';"); |
| | | if (count == 0) { |
| | | // 插入数据 |
| | | std::string insertSQL = "INSERT INTO SystemSV (ID, Name, DataType, Length, Unit, Remark, SystemID) VALUES (" |
| | | + std::to_string(nID) + ", '" |
| | | + sName + "', '" |
| | | + sDataType + "', " |
| | | + (nLength > 0 ? std::to_string(nLength) : "NULL") + ", " |
| | | + ((sUnit == "NULL") ? "NULL" : "'" + sUnit + "'") + ", '" |
| | | + sRemark + "', " |
| | | + std::to_string(nSystemID) + ");"; |
| | | |
| | | if (!m_pDB->executeQuery(insertSQL)) { |
| | | throw std::runtime_error("Failed to insert SystemSV data."); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 添加 SystemSV 数据 |
| | | int SECSRuntimeManager::addSystemSV(int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID) { |
| | | return addSystemVData("SystemSV", nID, sName, sDataType, nLength, sUnit, sRemark, nSystemID); |
| | | } |
| | | |
| | | // 获取指定 ID 的 SystemSV 数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getSystemSVByID(int nID) { |
| | | return getSystemVByID("SystemSV", nID); |
| | | } |
| | | |
| | | // 获取所有 SystemSV 数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getAllSystemSV() { |
| | | return getAllSystemV("SystemSV"); |
| | | } |
| | | |
| | | // 更新 SystemSV 表中的 ID |
| | | int SECSRuntimeManager::updateIDSystemSV(int nID, int sNewID) { |
| | | return updateIDSystemV("SystemSV", nID, sNewID); |
| | | } |
| | | |
| | | // 更新所有 SystemSV 数据 |
| | | int SECSRuntimeManager::updateAllSystemSV(int nID, int sNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID) { |
| | | return updateAllSystemV("SystemSV", nID, sNewID, sName, sDataType, nLength, sUnit, sRemark, nSystemID); |
| | | } |
| | | |
| | | // 删除指定 ID 的 SystemSV 数据 |
| | | int SECSRuntimeManager::deleteSystemSVByID(int nID) { |
| | | return deleteDataByID("SystemSV", nID); |
| | | } |
| | | |
| | | // 删除所有 SystemSV 数据 |
| | | int SECSRuntimeManager::deleteAllSystemSV() { |
| | | return deleteAllDataFromTable("SystemSV"); |
| | | } |
| | | |
| | | // 初始化 EqpSV 表 |
| | | void SECSRuntimeManager::initEqpSVTable() { |
| | | initEqpVTable("EqpSV"); |
| | | } |
| | | |
| | | // 添加 EqpSV 数据 |
| | | int SECSRuntimeManager::addEqpSV(int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo) { |
| | | return addEqpVData("EqpSV", nID, sName, sDataType, nLength, sUnit, sRemark, nSeqNo); |
| | | } |
| | | |
| | | // 查找指定 ID 的 EqpSV 数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getEqpSVByID(int nID) { |
| | | return getEqpVDataByID("EqpSV", nID); |
| | | } |
| | | |
| | | // 查找所有 EqpSV 数据 |
| | | bool SECSRuntimeManager::getAllEqpSV(std::vector<std::vector<std::string>>& outEqpSV) { |
| | | return getAllDataFromTable("EqpSV", outEqpSV); |
| | | } |
| | | |
| | | // 更新 EqpSV 表指定 ID 的数据 |
| | | int SECSRuntimeManager::updateEqpSV(int nID, int nNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo) { |
| | | return updateEqpV("EqpSV", nID, nNewID, sName, sDataType, nLength, sUnit, sRemark, nSeqNo); |
| | | } |
| | | |
| | | // 删除 EqpSV 表指定 ID 的数据 |
| | | int SECSRuntimeManager::deleteEqpSVByID(int nID) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return 1; |
| | | } |
| | | |
| | | // 检查是否存在该 ID |
| | | if (!isIDDuplicate(nID)) { |
| | | return 2; // 如果 ID 不存在,返回错误代码 2 |
| | | } |
| | | |
| | | // 构建删除 SQL 语句 |
| | | std::string deleteSQL = "DELETE FROM EqpSV WHERE ID = " + std::to_string(nID) + ";"; |
| | | if (!m_pDB->executeQuery(deleteSQL)) { |
| | | return 3; // 如果删除失败,返回错误代码 3 |
| | | } |
| | | |
| | | return 0; // 删除成功,返回 0 |
| | | return deleteDataByID("EqpSV", nID); |
| | | } |
| | | |
| | | // 删除 EqpSV 表中的所有数据 |
| | | int SECSRuntimeManager::deleteAllEqpSV() { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | return 1; |
| | | } |
| | | |
| | | // 构建删除所有数据的 SQL 语句 |
| | | std::string deleteSQL = "DELETE FROM EqpSV;"; |
| | | if (!m_pDB->executeQuery(deleteSQL)) { |
| | | return 2; // 如果删除失败,返回错误代码 2 |
| | | } |
| | | |
| | | return 0; // 删除成功,返回 0 |
| | | return deleteAllDataFromTable("EqpSV"); |
| | | } |
| | | |
| | | // 初始化 SystemDV 表 |
| | | void SECSRuntimeManager::initSystemDVTable() { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | throw std::runtime_error("Database not connected."); |
| | | initSystemVTable("SystemDV"); |
| | | } |
| | | |
| | | // 创建 SystemDV 表 |
| | | std::string createTableSQL = |
| | | "CREATE TABLE IF NOT EXISTS SystemDV (" |
| | | "ID INTEGER PRIMARY KEY, " |
| | | "Name TEXT UNIQUE NOT NULL, " |
| | | "DataType TEXT NOT NULL, " |
| | | "Length INTEGER NULL, " |
| | | "Unit TEXT NULL, " |
| | | "Remark TEXT, " |
| | | "SystemID INTEGER);"; |
| | | |
| | | if (!m_pDB->executeQuery(createTableSQL)) { |
| | | throw std::runtime_error("Failed to create SystemDV table."); |
| | | // 添加 SystemDV 数据 |
| | | int SECSRuntimeManager::addSystemDV(int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID) { |
| | | return addSystemVData("SystemDV", nID, sName, sDataType, nLength, sUnit, sRemark, nSystemID); |
| | | } |
| | | |
| | | // 获取指定 ID 的 SystemDV 数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getSystemDVByID(int nID) { |
| | | return getSystemVByID("SystemDV", nID); |
| | | } |
| | | |
| | | // 获取所有 SystemDV 数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getAllSystemDV() { |
| | | return getAllSystemV("SystemDV"); |
| | | } |
| | | |
| | | // 更新 SystemDV 表中的 ID |
| | | int SECSRuntimeManager::updateIDSystemDV(int nID, int sNewID) { |
| | | return updateIDSystemV("SystemDV", nID, sNewID); |
| | | } |
| | | |
| | | // 更新所有 SystemDV 数据 |
| | | int SECSRuntimeManager::updateAllSystemDV(int nID, int sNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID) { |
| | | return updateAllSystemV("SystemDV", nID, sNewID, sName, sDataType, nLength, sUnit, sRemark, nSystemID); |
| | | } |
| | | |
| | | // 删除指定 ID 的 SystemDV 数据 |
| | | int SECSRuntimeManager::deleteSystemDVByID(int nID) { |
| | | return deleteDataByID("SystemDV", nID); |
| | | } |
| | | |
| | | // 删除所有 SystemDV 数据 |
| | | int SECSRuntimeManager::deleteAllSystemDV() { |
| | | return deleteAllDataFromTable("SystemDV"); |
| | | } |
| | | |
| | | // 初始化 EqpDV 表 |
| | | void SECSRuntimeManager::initEqpDVTable() { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | if (m_pDB == nullptr) { |
| | | throw std::runtime_error("Database not connected."); |
| | | initEqpVTable("EqpDV"); |
| | | } |
| | | |
| | | // 创建 EqpDV 表 |
| | | std::string createTableSQL = |
| | | "CREATE TABLE IF NOT EXISTS EqpDV (" |
| | | "ID INTEGER PRIMARY KEY, " |
| | | "Name TEXT UNIQUE NOT NULL, " |
| | | "DataType TEXT NOT NULL, " |
| | | "Length INTEGER NULL, " |
| | | "Unit TEXT NULL, " |
| | | "Remark TEXT, " |
| | | "SeqNo INTEGER);"; |
| | | |
| | | if (!m_pDB->executeQuery(createTableSQL)) { |
| | | throw std::runtime_error("Failed to create EqpDV table."); |
| | | // 添加 EqpDV 数据 |
| | | int SECSRuntimeManager::addEqpDV(int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo) { |
| | | return addEqpVData("EqpDV", nID, sName, sDataType, nLength, sUnit, sRemark, nSeqNo); |
| | | } |
| | | |
| | | // 查找指定 ID 的 EqpDV 数据 |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getEqpDVByID(int nID) { |
| | | return getEqpVDataByID("EqpDV", nID); |
| | | } |
| | | |
| | | // 获取所有 EqpDV 数据 |
| | | bool SECSRuntimeManager::getAllEqpDV(std::vector<std::vector<std::string>>& outEqpDV) { |
| | | return getAllDataFromTable("EqpDV", outEqpDV); |
| | | } |
| | | |
| | | // 更新 EqpDV 表指定 ID 的数据 |
| | | int SECSRuntimeManager::updateEqpDV(int nID, int nNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo) { |
| | | return updateEqpV("EqpDV", nID, nNewID, sName, sDataType, nLength, sUnit, sRemark, nSeqNo); |
| | | } |
| | | |
| | | // 删除 EqpDV 表指定 ID 的数据 |
| | | int SECSRuntimeManager::deleteEqpDVByID(int nID) { |
| | | return deleteDataByID("EqpDV", nID); |
| | | } |
| | | |
| | | // 删除 EqpDV 表中的所有数据 |
| | | int SECSRuntimeManager::deleteAllEqpDV() { |
| | | return deleteAllDataFromTable("EqpDV"); |
| | | } |
| | | |
| | | // 初始化 SystemEC 表 |
| | |
| | | void termRuntimeSetting(); |
| | | |
| | | /** |
| | | * 初始化指定的 SystemV 表 |
| | | * @param tableName: 要初始化的表名(如 "SystemSV" 或 "SystemDV")。 |
| | | * |
| | | * 此函数用于初始化指定名称的 SystemV 表。如果表不存在,将会创建该表。 |
| | | * - 表结构包括:ID、Name、DataType、Length、Unit、Remark、SystemID。 |
| | | * - 如果表已经存在,则不进行任何操作。 |
| | | */ |
| | | void initSystemVTable(const std::string& tableName); |
| | | |
| | | int addSystemVData(const std::string& tableName, int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID); |
| | | |
| | | std::vector<std::vector<std::string>> getSystemVByID(const std::string& tableName, int nID); |
| | | |
| | | std::vector<std::vector<std::string>> getAllSystemV(const std::string& tableName); |
| | | |
| | | int updateIDSystemV(const std::string& tableName, int nID, int sNewID); |
| | | |
| | | int updateAllSystemV(const std::string& tableName, int nID, int sNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID); |
| | | |
| | | void initEqpVTable(const std::string& tableName); |
| | | |
| | | int addEqpVData(const std::string& tableName, int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo); |
| | | |
| | | std::vector<std::vector<std::string>> getEqpVDataByID(const std::string& tableName, int nID); |
| | | |
| | | int updateEqpV(const std::string& tableName, int nID, int nNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo); |
| | | |
| | | /** |
| | | * 初始化SystemSV表 |
| | | */ |
| | | void initSystemSVTable(); |
| | |
| | | |
| | | /** |
| | | * 获取所有 EqpSV 数据 |
| | | * @return std::vector<std::vector<std::string>>: 返回一个二维字符串向量,表示查询结果。每行代表一条记录,每列代表该记录的一个字段值。 |
| | | * 如果表中有数据,则返回所有记录;如果表为空,则返回空的二维向量。 |
| | | * |
| | | * 此函数用于从 EqpSV 表中获取所有的数据。通过构造 SQL 查询语句来选择所有记录,并执行查询操作。 |
| | | * 返回的结果是一个二维字符串向量,表示表中的所有记录。每行数据是一个字符串向量,其中包含该记录的各个字段。 |
| | | * 如果表中没有数据,函数将返回一个空的二维向量。 |
| | | */ |
| | | std::vector<std::vector<std::string>> SECSRuntimeManager::getAllEqpSV(); |
| | | bool getAllEqpSV(std::vector<std::vector<std::string>>& outEqpSV); |
| | | |
| | | /** |
| | | * 更新指定 ID 的 EqpSV 数据 |
| | |
| | | */ |
| | | void initSystemDVTable(); |
| | | |
| | | int addSystemDV(int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID); |
| | | |
| | | std::vector<std::vector<std::string>> getSystemDVByID(int nID); |
| | | |
| | | std::vector<std::vector<std::string>> getAllSystemDV(); |
| | | |
| | | int updateIDSystemDV(int nID, int sNewID); |
| | | |
| | | int updateAllSystemDV(int nID, int sNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID); |
| | | |
| | | int deleteSystemDVByID(int nID); |
| | | |
| | | int deleteAllSystemDV(); |
| | | |
| | | /** |
| | | * 初始化 EqpDV 表 |
| | | */ |
| | | void initEqpDVTable(); |
| | | |
| | | int addEqpDV(int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo); |
| | | |
| | | std::vector<std::vector<std::string>> getEqpDVByID(int nID); |
| | | |
| | | bool getAllEqpDV(std::vector<std::vector<std::string>>& outEqpDV); |
| | | |
| | | int updateEqpDV(int nID, int nNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo); |
| | | |
| | | int deleteEqpDVByID(int nID); |
| | | |
| | | int deleteAllEqpDV(); |
| | | |
| | | /** |
| | | * 初始化 SystemEC 表 |
| | |
| | | // 判断名称是否重复 |
| | | bool isNameDuplicate(const std::string& sName); |
| | | |
| | | // 删除指定表中的所有数据 |
| | | int deleteAllDataFromTable(const std::string& tableName); |
| | | |
| | | // 查询指定表所有数据(通用函数) |
| | | bool getAllDataFromTable(const std::string& tableName, std::vector<std::vector<std::string>>& outData); |
| | | |
| | | // 删除指定表中指定 ID 的数据 |
| | | int deleteDataByID(const std::string& tableName, int nID); |
| | | |
| | | BL::Database* m_pDB; |
| | | static std::mutex m_mutex; |
| | | }; |
| | |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | return FALSE; |
| | | } |
| | | AlarmManager::getInstance().insertMockData(); |
| | | |
| | | |
| | | // 初始化SECS运行设置管理库 |
| | |
| | | <Text Include="ReadMe.txt" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClInclude Include="AlarmDlg.h" /> |
| | | <ClInclude Include="AlarmManager.h" /> |
| | | <ClInclude Include="BlButton.h" /> |
| | | <ClInclude Include="CBonder.h" /> |
| | |
| | | <ClInclude Include="ToolUnits.h" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClCompile Include="AlarmDlg.cpp" /> |
| | | <ClCompile Include="AlarmManager.cpp" /> |
| | | <ClCompile Include="BlButton.cpp" /> |
| | | <ClCompile Include="CBonder.cpp" /> |
| | |
| | | <ClCompile Include="CEqModeStep.cpp" /> |
| | | <ClCompile Include="CEqStatusStep.cpp" /> |
| | | <ClCompile Include="CEqAlarmStep.cpp" /> |
| | | <ClCompile Include="AlarmDlg.cpp" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClInclude Include="AlarmManager.h" /> |
| | |
| | | <ClInclude Include="CEqModeStep.h" /> |
| | | <ClInclude Include="CEqStatusStep.h" /> |
| | | <ClInclude Include="CEqAlarmStep.h" /> |
| | | <ClInclude Include="AlarmDlg.h" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="Servo.rc" /> |
| | |
| | | <RemoteDebuggerCommand>D:\CLH\Servo\Servo.exe</RemoteDebuggerCommand> |
| | | <RemoteDebuggerWorkingDirectory>D:\CLH\Servo\</RemoteDebuggerWorkingDirectory> |
| | | <RemoteDebuggerServerName>Boounion-0106</RemoteDebuggerServerName> |
| | | <DebuggerFlavor>WindowsRemoteDebugger</DebuggerFlavor> |
| | | <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> |
| | | </PropertyGroup> |
| | | </Project> |
| | |
| | | #include "Common.h" |
| | | #include "Log.h" |
| | | #include "SecsTestDlg.h" |
| | | #include "AlarmDlg.h" |
| | | #include <chrono> |
| | | #include <thread> |
| | | #include <cmath> |
| | |
| | | m_crBkgnd = APPDLG_BACKGROUND_COLOR; |
| | | m_hbrBkgnd = nullptr; |
| | | m_bShowLogWnd = FALSE; |
| | | m_bShowAlarmWnd = FALSE; |
| | | m_bIsRobotMoving = FALSE; |
| | | m_pLogDlg = nullptr; |
| | | m_pTerminalDisplayDlg = nullptr; |
| | |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_BUTTON_LOG, m_btnLog); |
| | | DDX_Control(pDX, IDC_BUTTON_ALARM, m_btnAlarm); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CServoDlg, CDialogEx) |
| | |
| | | ON_WM_INITMENUPOPUP() |
| | | ON_WM_TIMER() |
| | | ON_WM_ERASEBKGND() |
| | | ON_BN_CLICKED(IDC_BUTTON_ALARM, &CServoDlg::OnBnClickedButtonAlarm) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | |
| | | InitRxWindows(); |
| | | OnBnClickedButtonLog(); |
| | | UpdateLogBtn(); |
| | | UpdateAlarmBtn(); |
| | | Resize(); |
| | | |
| | | |
| | |
| | | m_btnLog.Invalidate(); |
| | | } |
| | | |
| | | void CServoDlg::UpdateAlarmBtn() |
| | | { |
| | | m_btnAlarm.SetFrameColor(BS_NORMAL, BTN_ALARM_FRAME_NORMAL); |
| | | m_btnAlarm.SetFrameColor(BS_HOVER, BTN_ALARM_FRAME_HOVER); |
| | | m_btnAlarm.SetFrameColor(BS_PRESS, BTN_ALARM_FRAME_PRESS); |
| | | m_btnAlarm.SetBkgndColor(BS_NORMAL, m_bShowAlarmWnd ? BTN_ALARM_BKGND_PRESS : BTN_ALARM_BKGND_NORMAL); |
| | | m_btnAlarm.SetBkgndColor(BS_HOVER, BTN_ALARM_BKGND_HOVER); |
| | | m_btnAlarm.SetBkgndColor(BS_PRESS, BTN_ALARM_BKGND_PRESS); |
| | | m_btnAlarm.Invalidate(); |
| | | } |
| | | |
| | | void CServoDlg::UpdateRobotPosition(float percentage) |
| | | { |
| | | // 限制百分比范围在 [0, 1] 之间 |
| | |
| | | |
| | | switch (status) { |
| | | case ONLINE: |
| | | newBackgroundColor = RGB(255, 0, 0); |
| | | newBackgroundColor = RGB(0, 255, 0); |
| | | newFrameColor1 = RGB(22, 22, 22); |
| | | newFrameColor2 = RGB(255, 127, 39); |
| | | break; |
| | | case OFFLINE: |
| | | newBackgroundColor = RGB(0, 255, 0); |
| | | newBackgroundColor = RGB(255, 0, 0); |
| | | newFrameColor1 = RGB(22, 22, 22); |
| | | newFrameColor2 = RGB(255, 127, 39); |
| | | break; |
| | |
| | | |
| | | x = 8; |
| | | pItem = GetDlgItem(IDC_BUTTON_LOG); |
| | | pItem->GetClientRect(&rcItem); |
| | | pItem->MoveWindow(x, rcClient.bottom - 8 - rcItem.Height(), rcItem.Width(), rcItem.Height()); |
| | | |
| | | x = 20 + rcItem.Width(); |
| | | pItem = GetDlgItem(IDC_BUTTON_ALARM); |
| | | pItem->GetClientRect(&rcItem); |
| | | pItem->MoveWindow(x, rcClient.bottom - 8 - rcItem.Height(), rcItem.Width(), rcItem.Height()); |
| | | } |
| | |
| | | |
| | | return CDialogEx::OnEraseBkgnd(pDC); |
| | | } |
| | | |
| | | |
| | | void CServoDlg::OnBnClickedButtonAlarm() |
| | | { |
| | | // TODO: 在此添加控件通知处理程序代码 |
| | | CAlarmDlg dlg; |
| | | dlg.DoModal(); |
| | | } |
| | |
| | | void InitRxWindows(); |
| | | void Resize(); |
| | | void UpdateLogBtn(); |
| | | void UpdateAlarmBtn(); |
| | | void UpdateRobotPosition(float percentage); |
| | | void RotateRobot(float angleInDegrees); |
| | | void UpdateDeviceStatus(int id, DeviceStatus status); |
| | |
| | | private: |
| | | IObserver* m_pObserver; |
| | | BOOL m_bShowLogWnd; |
| | | BOOL m_bShowAlarmWnd; |
| | | CLogDlg* m_pLogDlg; |
| | | CTerminalDisplayDlg* m_pTerminalDisplayDlg; |
| | | |
| | |
| | | COLORREF m_crBkgnd; |
| | | HBRUSH m_hbrBkgnd; |
| | | CBlButton m_btnLog; |
| | | CBlButton m_btnAlarm; |
| | | |
| | | |
| | | // 生成的消息映射函数 |
| | |
| | | afx_msg void OnMenuHelpAbout(); |
| | | afx_msg void OnTimer(UINT_PTR nIDEvent); |
| | | afx_msg BOOL OnEraseBkgnd(CDC* pDC); |
| | | afx_msg void OnBnClickedButtonAlarm(); |
| | | }; |
| | |
| | | |
| | | return std::string(buffer); |
| | | } |
| | | |
| | | bool CToolUnits::startsWith(const std::string& str, const std::string& prefix) |
| | | { |
| | | return str.size() >= prefix.size() && str.compare(0, prefix.size(), prefix) == 0; |
| | | } |
| | |
| | | static std::vector<CString> GetFileNamesInDirectory(const CString& strFolderPath, const CString& strExtension); |
| | | static std::string getRecipePath(); |
| | | static std::string getCurrentTimeString(); |
| | | static bool startsWith(const std::string& str, const std::string& prefix); |
| | | }; |
| | | |