Files
EJM_Display/DataCenter/DataCenter.cpp
2025-08-20 23:06:28 +08:00

140 lines
4.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "DataCenter.h"
#include <QDebug>
#include <FileOperation/ConfigFiles.h>
DataCenter::DataCenter(OpcUaManager *opcManager, QObject *parent)
: QObject(parent)
, m_opcManager(opcManager)
, m_cyclicTimer(new QTimer(this))
, m_currentReadIndex(0)
{
Q_ASSERT(opcManager != nullptr); // 确保OPC管理器有效
// 连接定时器
connect(m_cyclicTimer, &QTimer::timeout, this, &DataCenter::onTimerTimeout);
// 连接OPC读取信号仅处理数据读取逻辑
connect(m_opcManager, &OpcUaManager::readCompleted,
this, &DataCenter::handleReadCompleted);
// 转发错误信号
connect(m_opcManager, &OpcUaManager::errorOccurred,
this, &DataCenter::errorOccurred);
connect(m_opcManager, &OpcUaManager::reconnected,
this, &DataCenter::refreshAllNodes);
}
//
void DataCenter::InitData(){
QList<QStringList> FileData = ConfigFiles().ReadFile_Csv("./ProgramConfig/OpcUA_Node_Config.csv");
for (int row = 1; row < FileData.size()-1; ++row)
{
addMonitoredNode(FileData.at(row)[3], FileData.at(row)[0],FileData.at(row)[2],FileData.at(row)[1],FileData.at(row)[2]);
}
}
// 添加监控节点仅数据层操作不涉及UI
void DataCenter::addMonitoredNode(const QString &nodeId, const QString &nodeName,const QString &varName,const QString &TableName,const QString &FieldName)
{
if (gOPC_NodeName.contains(nodeId)) {
qWarning() << "节点已存在:" << nodeId;
return;
}
QString NName = nodeName.isEmpty() ? nodeId : nodeName;
QString VName = varName.isEmpty() ? nodeId : varName;
gOPC_NodeName[nodeId] = NName;
gOPC_VarName[nodeId] = VName;
gOPC_SqlTable[nodeId] = TableName;
gOPC_SqlField[nodeId] = FieldName;
gOPC_NodeList.append(nodeId);
gOPC_NodeValue[nodeId] = QVariant(); // 初始化值
}
// 开始循环读取(纯数据操作)
void DataCenter::startCyclicRead(int intervalMs)
{
if (gOPC_NodeList.isEmpty()) {
emit errorOccurred("没有需要监控的节点,请先添加节点");
return;
}
int actualInterval = qMax(intervalMs, 3); // 最小间隔100ms
m_cyclicTimer->stop(); // <-- 关键:先停
m_cyclicTimer->start(actualInterval); // <-- 再启
m_currentReadIndex = 0;
}
// 停止循环读取
void DataCenter::stopCyclicRead()
{
m_cyclicTimer->stop();
}
void DataCenter::refreshAllNodes()
{
if (gOPC_NodeList.isEmpty())
return;
// 重置索引
m_currentReadIndex = 0;
// 如果定时器没开,重新启动它
if (!m_cyclicTimer->isActive()) {
m_cyclicTimer->start(); // 使用之前设置的间隔
}
// 立即触发一次读取(可选)
onTimerTimeout();
}
// 通过节点ID获取值
QVariant DataCenter::getNodeValue(const QString &nodeId) const
{
return gOPC_NodeValue.value(nodeId, QVariant());
}
// 通过节点名称获取值
QVariant DataCenter::getNodeValueByName(const QString &nodeName) const
{
for (auto it = gOPC_NodeName.constBegin(); it != gOPC_NodeName.constEnd(); ++it) {
if (it.value() == nodeName) {
return gOPC_NodeValue.value(it.key(), QVariant());
}
}
return QVariant();
}
// 定时器触发,循环读取下一个节点(纯数据逻辑)
void DataCenter::onTimerTimeout()
{
if (gOPC_NodeList.isEmpty()) return;
// 循环索引处理
if (m_currentReadIndex >= gOPC_NodeList.size()) {
m_currentReadIndex = 0;
}
// 读取当前节点(仅数据操作)
QString nodeId = gOPC_NodeList[m_currentReadIndex];
if (!m_opcManager->readNodeValue(nodeId)) {
emit errorOccurred("读取节点失败: " + nodeId);
m_currentReadIndex++; // 无论成功与否都移动到下一个
}
}
// 处理读取结果并缓存(仅数据处理)
void DataCenter::handleReadCompleted(const QVariant &value, const QString &nodeId)
{
if (!gOPC_NodeName.contains(nodeId)) return;
// 更新缓存值
gOPC_NodeValue[nodeId] = value;
// 发送更新信号仅传递数据不涉及UI
emit nodeValueUpdated(nodeId, gOPC_NodeName[nodeId],gOPC_VarName[nodeId], value);
// 移动到下一个节点
m_currentReadIndex++;
// if(DC_SetST.funts_SetSysInitOjb(gSysInfo,gOPC_VarName[nodeId],value)) return;
// else if (DC_SetST.funts_SetSysInitOjb(gSysInfo,gOPC_VarName[nodeId],value)) return;
}