| | |
| | | m_listener.onEQOffLine = nullptr; |
| | | m_listener.onEQOnLine = nullptr; |
| | | m_listener.onCommand = nullptr; |
| | | m_listener.onEQConstantRequest = nullptr; |
| | | m_listener.onEQConstantSend = nullptr; |
| | | m_pActiveAction = nullptr; |
| | | InitializeCriticalSection(&m_criticalSection); |
| | | } |
| | |
| | | SERVO::CReport* pReport = new SERVO::CReport(RPTID, vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable(vid); |
| | | if (pVariable == nullptr) { |
| | | pVariable = getDataVariable(vid); |
| | | } |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | LOGI("<CHsmsPassive>defineReport RPTID=%d", RPTID); |
| | |
| | | return 0; |
| | | } |
| | | |
| | | int CHsmsPassive::loadEquipmentConstants(const char* pszFilepath) |
| | | { |
| | | if (pszFilepath == NULL) return -1; |
| | | m_strEquipmentConstantFilepath = pszFilepath; |
| | | m_bEquipmentConstantUtf8 = false; |
| | | m_bEquipmentConstantUtf8Bom = false; |
| | | |
| | | CFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | const ULONGLONG nLen = file.GetLength(); |
| | | if (nLen == 0) { |
| | | return -1; |
| | | } |
| | | std::string buffer; |
| | | buffer.resize(static_cast<size_t>(nLen)); |
| | | file.Read(buffer.data(), static_cast<UINT>(nLen)); |
| | | file.Close(); |
| | | |
| | | if (hasUtf8Bom(buffer)) { |
| | | m_bEquipmentConstantUtf8 = true; |
| | | m_bEquipmentConstantUtf8Bom = true; |
| | | buffer = buffer.substr(3); |
| | | } |
| | | else if (isLikelyUtf8(buffer)) { |
| | | m_bEquipmentConstantUtf8 = true; |
| | | } |
| | | CStringW content = m_bEquipmentConstantUtf8 ? Utf8ToWide(buffer.c_str()) : AnsiToWide(buffer.c_str()); |
| | | if (content.IsEmpty()) return -1; |
| | | |
| | | std::wregex pattern(L"^\\d+,[^,]*,[^,]*,([^,]*),.*"); |
| | | std::vector<EquipmentConstantEntry> constants; |
| | | CStringW strLine, strId, strName, strFormat, strRemark, strDefault; |
| | | std::wstringstream ss(content.GetString()); |
| | | auto narrowFromW = [](const CStringW& s) -> std::string { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return {}; |
| | | std::string out(static_cast<size_t>(need - 1), '\0'); |
| | | WideCharToMultiByte(CP_ACP, 0, s, -1, out.data(), need, nullptr, nullptr); |
| | | return out; |
| | | }; |
| | | std::wstring line; |
| | | while (std::getline(ss, line, L'\n')) { |
| | | strLine = line.c_str(); |
| | | strLine.Trim(); |
| | | if (strLine.IsEmpty()) continue; |
| | | if (strLine.Find(L"ECID") == 0) continue; // skip header |
| | | if (!std::regex_match(static_cast<LPCWSTR>(strLine), pattern)) { |
| | | continue; |
| | | } |
| | | int last = 0; |
| | | int idx = strLine.Find(L",", last); |
| | | if (idx < 0) continue; |
| | | strId = strLine.Left(idx); |
| | | last = idx + 1; |
| | | |
| | | idx = strLine.Find(L",", last); |
| | | if (idx < 0) continue; |
| | | strName = strLine.Mid(last, idx - last); |
| | | last = idx + 1; |
| | | |
| | | idx = strLine.Find(L",", last); |
| | | if (idx < 0) continue; |
| | | strFormat = strLine.Mid(last, idx - last); |
| | | last = idx + 1; |
| | | |
| | | idx = strLine.Find(L",", last); |
| | | if (idx < 0) continue; |
| | | strRemark = strLine.Mid(last, idx - last); |
| | | last = idx + 1; |
| | | |
| | | strDefault = strLine.Right(strLine.GetLength() - last); |
| | | |
| | | EquipmentConstantEntry entry; |
| | | entry.id = _wtoi(strId); |
| | | entry.name = narrowFromW(strName); |
| | | entry.format = narrowFromW(strFormat); |
| | | entry.remark = narrowFromW(strRemark); |
| | | entry.value = narrowFromW(strDefault); |
| | | constants.push_back(entry); |
| | | } |
| | | |
| | | if (!constants.empty()) { |
| | | m_equipmentConstants = std::move(constants); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | std::vector<SERVO::CVariable*>& CHsmsPassive::getVariables() |
| | | { |
| | | return m_variabels; |
| | |
| | | if (auto v = getVariable(pszName)) { |
| | | v->setValue(value); |
| | | } |
| | | else if (auto dv = getDataVariable(pszName)) { |
| | | dv->setValue(value); |
| | | } |
| | | Unlock(); |
| | | } |
| | | |
| | |
| | | if (auto v = getVariable(pszName)) { |
| | | v->setValue(value); |
| | | } |
| | | else if (auto dv = getDataVariable(pszName)) { |
| | | dv->setValue(value); |
| | | } |
| | | Unlock(); |
| | | } |
| | | |
| | |
| | | Lock(); |
| | | if (auto v = getVariable(pszName)) { |
| | | v->setValue(vars); |
| | | } |
| | | else if (auto dv = getDataVariable(pszName)) { |
| | | dv->setValue(vars); |
| | | } |
| | | Unlock(); |
| | | } |
| | |
| | | SERVO::CReport* pReport = new SERVO::CReport(_wtoi(strId), vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable(vid); |
| | | if (pVariable == nullptr) { |
| | | pVariable = getDataVariable(vid); |
| | | } |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | } |
| | |
| | | SERVO::CReport* pReport = new SERVO::CReport(rptid, vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable((int)vid); |
| | | if (pVariable == nullptr) { |
| | | pVariable = getDataVariable((int)vid); |
| | | } |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | } |
| | |
| | | SERVO::CReport* pReport = new SERVO::CReport(rptid, vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable((int)vid); |
| | | if (pVariable == nullptr) { |
| | | pVariable = getDataVariable((int)vid); |
| | | } |
| | | if (pVariable != nullptr) { |
| | | pReport->addVariable(pVariable); |
| | | } |
| | |
| | | return ER_NOERROR; |
| | | } |
| | | |
| | | int CHsmsPassive::writeEquipmentConstantsToFile(const std::string& filepath) |
| | | { |
| | | if (filepath.empty()) return -1; |
| | | CFile file; |
| | | if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | const std::string headerAnsi = "ECID,EC Name,EC Format,EC Remark,Default Value\r\n"; |
| | | if (m_bEquipmentConstantUtf8) { |
| | | if (m_bEquipmentConstantUtf8Bom) { |
| | | const BYTE bom[3] = { 0xEF, 0xBB, 0xBF }; |
| | | file.Write(bom, 3); |
| | | } |
| | | CStringA header = AnsiToUtf8(headerAnsi); |
| | | file.Write(header.GetString(), header.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(headerAnsi.data(), (UINT)headerAnsi.size()); |
| | | } |
| | | for (const auto& e : m_equipmentConstants) { |
| | | std::string line; |
| | | line.reserve(128); |
| | | line += std::to_string(e.id); |
| | | line.push_back(','); |
| | | line += e.name; |
| | | line.push_back(','); |
| | | line += e.format; |
| | | line.push_back(','); |
| | | line += e.remark; |
| | | line.push_back(','); |
| | | line += e.value; |
| | | line.append("\r\n"); |
| | | if (m_bEquipmentConstantUtf8) { |
| | | CStringA out = AnsiToUtf8(line); |
| | | file.Write(out.GetString(), out.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(line.data(), (UINT)line.size()); |
| | | } |
| | | } |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | // S1F21/S1F22 - Data Variable Namelist |
| | | int CHsmsPassive::replyDataVariableNamelistRequest(IMessage* pRecv) |
| | | { |
| | |
| | | } |
| | | |
| | | |
| | | // 要获取的常量表表 |
| | | BOOL bCheckData = FALSE; |
| | | std::vector<EQConstant> eqcs; |
| | | { |
| | | ISECS2Item* pItem = pRecv->getBody(); |
| | | int ecidSize = pItem->getSubItemSize(); |
| | | const int ecidSize = pItem ? pItem->getSubItemSize() : 0; |
| | | for (int i = 0; i < ecidSize; i++) { |
| | | EQConstant eqc; |
| | | unsigned short id; |
| | | if (pItem->getSubItemU2(i, id)) { |
| | | EQConstant eqc{}; |
| | | unsigned short id = 0; |
| | | if (pItem && pItem->getSubItemU2(i, id)) { |
| | | eqc.id = id; |
| | | eqcs.push_back(eqc); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 交由上层应用来获取机器常量值 |
| | | if (m_listener.onEQConstantRequest != nullptr) { |
| | | m_listener.onEQConstantRequest(this, eqcs); |
| | | // 空列表表示请求全部 ECID |
| | | if (eqcs.empty()) { |
| | | for (const auto& e : m_equipmentConstants) { |
| | | EQConstant eqc{}; |
| | | eqc.id = e.id; |
| | | strcpy_s(eqc.szValue, EQCONSTANT_VALUE_MAX, e.value.c_str()); |
| | | eqcs.push_back(eqc); |
| | | } |
| | | } else { |
| | | for (auto& item : eqcs) { |
| | | auto it = std::find_if(m_equipmentConstants.begin(), m_equipmentConstants.end(), |
| | | [&](const EquipmentConstantEntry& e) { return e.id == item.id; }); |
| | | if (it != m_equipmentConstants.end()) { |
| | | strcpy_s(item.szValue, EQCONSTANT_VALUE_MAX, it->value.c_str()); |
| | | } else { |
| | | item.szValue[0] = '\0'; // unknown -> empty |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 回复 |
| | | IMessage* pMessage = NULL; |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 1, 14, pRecv->getHeader()->systemBytes); |
| | | HSMS_Create1Message(pMessage, m_nSessionId, 2, 14, pRecv->getHeader()->systemBytes); |
| | | ASSERT(pMessage); |
| | | ISECS2Item* pItem = pMessage->getBody(); |
| | | for (auto& item : eqcs) { |
| | |
| | | } |
| | | |
| | | |
| | | // 要设置的常量表表 |
| | | BOOL bCheckData = FALSE; |
| | | // 要设置的常量表 |
| | | std::vector<EQConstant> eqcs; |
| | | { |
| | | ISECS2Item* pItem = pRecv->getBody(); |
| | | int ecidSize = pItem->getSubItemSize(); |
| | | int ecidSize = pItem ? pItem->getSubItemSize() : 0; |
| | | for (int i = 0; i < ecidSize; i++) { |
| | | ISECS2Item* pItemEqc = pItem->getSubItem(i); |
| | | if (pItemEqc != nullptr) { |
| | | EQConstant eqc; |
| | | unsigned short eqcid; |
| | | const char* pszValue; |
| | | if (pItemEqc->getSubItemU2(0, eqcid) |
| | | && pItemEqc->getSubItemString(1, pszValue)) { |
| | | eqc.id = eqcid; |
| | | strcpy_s(eqc.szValue, EQCONSTANT_VALUE_MAX, pszValue); |
| | | eqcs.push_back(eqc); |
| | | } |
| | | ISECS2Item* pItemEqc = pItem ? pItem->getSubItem(i) : nullptr; |
| | | if (pItemEqc == nullptr) continue; |
| | | EQConstant eqc{}; |
| | | unsigned short eqcid = 0; |
| | | const char* pszValue = nullptr; |
| | | if (pItemEqc->getSubItemU2(0, eqcid) |
| | | && pItemEqc->getSubItemString(1, pszValue)) { |
| | | eqc.id = eqcid; |
| | | strcpy_s(eqc.szValue, EQCONSTANT_VALUE_MAX, pszValue); |
| | | eqcs.push_back(eqc); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 交由上层应用来保存和设置机器常量值 |
| | | std::vector<unsigned int> ecvs; |
| | | if (m_listener.onEQConstantSend != nullptr) { |
| | | m_listener.onEQConstantSend(this, eqcs); |
| | | // 更新内存表并落盘 |
| | | bool changed = false; |
| | | for (auto& item : eqcs) { |
| | | auto it = std::find_if(m_equipmentConstants.begin(), m_equipmentConstants.end(), |
| | | [&](const EquipmentConstantEntry& e) { return e.id == item.id; }); |
| | | if (it != m_equipmentConstants.end()) { |
| | | it->value = item.szValue; |
| | | changed = true; |
| | | } |
| | | } |
| | | if (changed && !m_strEquipmentConstantFilepath.empty()) { |
| | | writeEquipmentConstantsToFile(m_strEquipmentConstantFilepath); |
| | | } |
| | | |
| | | |