Compare commits

...

10 Commits

Author SHA1 Message Date
edff1888cf 修改测量服务参数配置 2026-05-14 17:54:19 +08:00
81cba45eb2 添加测量gvf数据发送处理 2026-04-22 11:36:54 +08:00
738f07624c 添加GVF数据处理线程 2026-04-16 21:53:03 +08:00
64e0113290 调整测量服务架构 2026-04-16 20:26:41 +08:00
ef452e95e3 修改通信为长连接 2026-04-14 21:32:01 +08:00
871de1e005 调试修改 2026-04-14 10:16:36 +08:00
09be8c7efa 调试修改 2026-04-08 19:52:53 +08:00
e0648db32b 添加断开设备 2026-04-08 15:44:32 +08:00
eb6f1f946c 调试测量服务修改 2026-04-07 19:16:35 +08:00
e3b44605b3 更新DeviceManage.dll 2026-04-06 23:26:19 +08:00
29 changed files with 588 additions and 295 deletions

Binary file not shown.

View File

@ -317,13 +317,13 @@ typedef void(__stdcall *ONUPDATE_DEVICE_STRUCT)(void* pHandle,void *pParent,int
DEVICEMANAGE_API(int) FindDeviceAsync(sFindDeviceConfig *fdc, ONFINDDEVICEFINISHED OnFindFinished);
DEVICEMANAGE_API(int) GetDeviceInfo(void *pHandle, sDeviceInfo *spDi, int budnum, int chnum);
DEVICEMANAGE_API(int) GetDeviceBoardTotalNum(void *pHandle);
DEVICEMANAGE_API(int) GetDeviceChTotalNum(void *pHandle, int bdidx);
DEVICEMANAGE_API(int) GetDeviceChTotalNum(void *pHandle, int bdidx);
// DEVICEMANAGE_API(int) GetDeviceUserInfo(void *pHandle, UserConfigInfo *pUCI);
// DEVICEMANAGE_API(int) SetDeviceUserInfo(void *pHandle, UserConfigInfo *pUCI);
// DEVICEMANAGE_API(int) GetDeviceBoardUserInfo(void *pHandle, UserConfigInfo *pUCI, int bdidx);
// DEVICEMANAGE_API(int) GetDeviceBoardChannelUserInfo(void *pHandle, UserConfigInfo *pUCI, int bdidx, int chidx);
// DEVICEMANAGE_API(int) SetDeviceBoardChannelUserInfo(void *pHandle, UserConfigInfo *pUCI, int bdidx, int chidx);
DEVICEMANAGE_API(int) GetDeviceUserInfo(void *pHandle, UserConfigInfo *pUCI);
DEVICEMANAGE_API(int) SetDeviceUserInfo(void *pHandle, UserConfigInfo *pUCI);
DEVICEMANAGE_API(int) GetDeviceBoardUserInfo(void *pHandle, UserConfigInfo *pUCI, int bdidx);
DEVICEMANAGE_API(int) GetDeviceBoardChannelUserInfo(void *pHandle, UserConfigInfo *pUCI, int bdidx, int chidx);
DEVICEMANAGE_API(int) SetDeviceBoardChannelUserInfo(void *pHandle, UserConfigInfo *pUCI, int bdidx, int chidx);
DEVICEMANAGE_API(int) GetDeviceBoardChannelConfiginfo(void *pHandle, OneChannelConfigInfo *pUCI, int bdidx, int chidx);
DEVICEMANAGE_API(int) DBCSetHightVoltage(void *pHandle, OneChannelConfigInfo *pUCI, int bdidx, int chidx);

View File

@ -10,12 +10,12 @@ typedef int* DeviceHandler;
static sDeviceList s_device_list;
static DeviceHandler GetDeviceHandler(const QString &device_guid) {
DeviceHandler device_handler = nullptr;
DeviceHandler device_handler = DeviceHandler(0x01); // nullptr;
for (int i = 0; i < s_device_list.totalNum; i++) {
sDeviceInfo di;
int ret = GetDeviceInfo(s_device_list.pHandle[i], &di,-1,-1);
if (ret == 0) {
if (QString(di.GUID) == device_guid) {
if (QString(di.MacAddr) == device_guid) {
device_handler = s_device_list.pHandle[i];
}
} else {
@ -43,7 +43,6 @@ MeasureDeviceController *MeasureDeviceController::Instance()
MeasureDeviceController::~MeasureDeviceController()
{
}
void MeasureDeviceController::InitFindMeasureDevice()
@ -57,7 +56,19 @@ void MeasureDeviceController::InitFindMeasureDevice()
int ret = FindDeviceAsync(&fdc, onFindDeviceFinishedCallback);
if (ret != 1) {
QLOG_ERROR() << QStringLiteral(u"调用测量设备失败:[返回代码%1]").arg(ret);
QLOG_ERROR() << QStringLiteral(u"调用查找测量设备失败:[返回代码%1]").arg(ret);
}
}
void MeasureDeviceController::DisconnectMeasureDevice(const QString &device_guid)
{
DeviceHandler device_handler = GetDeviceHandler(device_guid);
if (!device_handler) {
return;
}
int ret = CloseDevice(device_handler);
if (ret != 1) {
QLOG_ERROR() << QStringLiteral(u"断开测量设备失败:[返回代码%1]").arg(ret);
}
}
@ -69,6 +80,8 @@ void MeasureDeviceController::onFindDeviceFinishedCallback(int ret, sDeviceList*
if ( s_device_list.totalNum == 0 ) {
init_ok &= false;
QLOG_WARN() << QStringLiteral(u"未找到测量设备!");
} else {
QLOG_DEBUG() << s_device_list.totalNum << GetMeasureDeviceList();
}
} else {
init_ok &= false;
@ -87,9 +100,9 @@ QStringList MeasureDeviceController::GetMeasureDeviceList()
QStringList device_guid_list;
for (int i = 0; i < s_device_list.totalNum; i++) {
sDeviceInfo di;
int ret = GetDeviceInfo(s_device_list.pHandle[i], &di,-1,-1);
int ret = GetDeviceInfo(s_device_list.pHandle[i], &di, 0, 1);
if (ret == 0) {
device_guid_list.append(QString(di.GUID));
device_guid_list.append(QString(di.MacAddr));
} else {
QLOG_ERROR() << QStringLiteral(u"处理查找测量设备结果信息失败: GetDeviceInfo调用失败索引%1,[返回代码%2]").arg(i).arg(ret);
}
@ -112,33 +125,17 @@ bool MeasureDeviceController::SetDeviceMeasureConfigParams(const QString &device
ok = false;
return ok;
}
config.m_eTransferModel = eTransferMode(cfg_params.value("TransferMode", 3).toInt());
config.m_iDeviceGain = cfg_params.value("DeviceGain", 1).toInt();
config.m_iDeviceGainSelectIndex = cfg_params.value("DeviceGainSelectIndex", 1).toInt();
config.m_iSoftGain = cfg_params.value("SoftGain", 3000).toInt();
config.m_iChannelNum = cfg_params.value("AddrCount", 256).toInt();
config.m_dConstTime = cfg_params.value("TimeConst", 45).toInt();
config.m_iSoftGain = cfg_params.value("SoftGain", 10000000).toInt();
config.m_iChannelNum = cfg_params.value("AddrCount", 4096).toInt();
config.m_dConstTime = cfg_params.value("TimeConst", 1).toDouble();
config.m_iCurrentOffset = cfg_params.value("DcOffset", 0).toInt();
config.m_iRiseTime = cfg_params.value("RiseTime", 2).toInt();
config.m_iTopTime = cfg_params.value("FlatTime", 2).toInt();
config.m_iMaxEnergy = cfg_params.value("MaxEnergy", 1).toInt();
config.m_iTotalMeasureTime = cfg_params.value("TotalMeasureTime", 10).toInt();
config.m_eTransferModel = eSpecturmMode;
config.m_iFormTime = 3;
config.m_iFastChannelTrigerValue = 10;
config.m_iHighVoltage = 0;
config.m_iInputVoltageDesc = 0;
config.m_iCRDivMode = 0;
config.m_iInputSignalPostive = 0;
config.m_iAMPeakDiv = 0;
config.m_iHVDelt = 0;
config.m_iHVCtrl = 0;
config.m_iGetSpecturmPeirod = 1;
config.m_iTotalMeasureCount = 0;
config.m_iTrapeTopShitBit = 0;
config.m_bICRCorrect = 0;
config.m_iCRZAValue = 0;
config.m_iZAEnable = 0;
config.m_iFormTime = cfg_params.value("FormTime", 2).toInt();
config.m_iFastChannelTrigerValue = cfg_params.value("FastChannelTrigerValue", 100).toDouble();
config.m_iCRDivMode = cfg_params.value("CRDivMode", 0).toInt();
config.m_iInputSignalPostive = cfg_params.value("InputSignalPostive", 0).toInt();
memset(config.reserve, 0, 128);
ret = DBCSoftParamConfig(device_handler, &config, board_id, channel_id);
@ -231,6 +228,12 @@ bool MeasureDeviceController::ClearData(const QString &device_guid)
return ok;
}
bool MeasureDeviceController::GetData(const QString &device_guid, int board_id, int channel_id)
{
bool ok = false;
return ok;
}
QString MeasureDeviceController::GetMeasureGvfDataFilename()
{
QString measure_gvf_data_filename;
@ -239,14 +242,14 @@ QString MeasureDeviceController::GetMeasureGvfDataFilename()
return QString();
}
QList<QString> gvf_file_list = measure_gvf_data_dir.entryList(QDir::Files|QDir::NoSymLinks|QDir::NoDotAndDotDot, QDir::Time);
for (const QString& gvf_filename : gvf_file_list) {
foreach (const QString& gvf_filename , gvf_file_list) {
QFileInfo measure_gvf_data_file_info(measure_gvf_data_dir.filePath(gvf_filename));
if (measure_gvf_data_file_info.exists()) {
if ( measure_gvf_data_file_info.suffix() != QString("gvf") )
continue;
QString measure_gvf_data_file_base_name = measure_gvf_data_file_info.baseName();
QDateTime data_time = QDateTime::fromString(measure_gvf_data_file_base_name, "GVHD__YYYY_MM_dd_hh_mm_ss_zzz");
if ( qAbs(_measure_start_time.toMSecsSinceEpoch() - data_time.toMSecsSinceEpoch()) < 1000 ) {
QString measure_gvf_datetime_str = measure_gvf_data_file_info.baseName().remove("GVHD__");
QDateTime data_time = QDateTime::fromString(measure_gvf_datetime_str, "yyyy_MM_dd_hh_mm_ss_zzz");
if ( qAbs(_measure_start_time.toMSecsSinceEpoch() - data_time.toMSecsSinceEpoch()) < (1000 * 10) ) {
measure_gvf_data_filename = measure_gvf_data_file_info.absoluteFilePath();
}
}

View File

@ -23,11 +23,13 @@ public:
virtual ~MeasureDeviceController();
void InitFindMeasureDevice();
void DisconnectMeasureDevice(const QString &device_guid);
bool SetDeviceMeasureConfigParams(const QString& device_guid, int board_id, int channel_id, const QVariantMap &cfg_params);
bool StartMeasure(const QString& device_guid, int board_id, int channel_id);
bool StopMeasure(const QString& device_guid, int board_id, int channel_id);
bool StopMeasure(const QString& device_guid);
bool ClearData(const QString& device_guid);
bool GetData(const QString& device_guid, int board_id, int channel_id);
QString GetMeasureGvfDataFilename();
static QStringList GetMeasureDeviceList();

View File

@ -1,5 +1,14 @@
#include "MeasureServer.h"
#include "MeasureTask.h"
#include "QsLogManage.h"
#include "MeasureDeviceController.h"
#include "MeasureServiceProtocol.h"
#include "RequstDataProcesser.h"
#include <QDataStream>
#include <QFileInfo>
#include <QHostAddress>
#include <QString>
#include <QThread>
#include <QDebug>
MeasureServer::MeasureServer(QObject *parent)
: QTcpServer(parent)
@ -8,7 +17,7 @@ MeasureServer::MeasureServer(QObject *parent)
bool MeasureServer::Start(quint16 port)
{
return this->listen(QHostAddress::Any, port);
return this->listen(QHostAddress::LocalHost, port);
}
void MeasureServer::Stop()
@ -16,10 +25,87 @@ void MeasureServer::Stop()
this->close();
}
void MeasureServer::incomingConnection(qintptr socketDescriptor)
void MeasureServer::incomingConnection(qintptr socket_descriptor)
{
MeasureTask * measure_thread = new MeasureTask(socketDescriptor);
connect(measure_thread, &MeasureTask::finished, measure_thread, &MeasureTask::deleteLater);
_measure_thread->start();
QLOG_INFO() << QStringLiteral(u"接收到新的请求连接") << socket_descriptor;
MeasureSession * measure_thread = new MeasureSession(socket_descriptor, this);
connect(measure_thread, &MeasureSession::finished, measure_thread, &MeasureSession::deleteLater);
measure_thread->start();
}
MeasureSession::MeasureSession(int socket_descriptor, QObject* parent)
: QThread(parent)
, _socket_descriptor(socket_descriptor)
, _tcp_socket(nullptr)
, _requst_buffer(new QByteArray)
, _requst_data_len(0)
{
}
MeasureSession::~MeasureSession()
{
QLOG_DEBUG() << QStringLiteral(u"~MeasureSession");
}
void MeasureSession::run()
{
// 在子线程中创建套接字(关键:必须在当前线程创建)
_tcp_socket = new RequstDataProcesser;
// 设置客户端套接字描述符(绑定连接)
if (!_tcp_socket->setSocketDescriptor(_socket_descriptor)) {
QLOG_ERROR() << QStringLiteral(u"套接字初始化失败:") << _tcp_socket->errorString();
return;
}
QLOG_INFO() << QStringLiteral(u"新客户端接入:") << _tcp_socket->peerAddress().toString()
<< QStringLiteral(u"端口:") << _tcp_socket->peerPort()
<< QStringLiteral(u"线程ID:") << QThread::currentThreadId();
// 绑定信号槽(长连接核心:持续监听数据/断开)
connect(_tcp_socket, &QTcpSocket::readyRead, this, &MeasureSession::onClientRequstData, Qt::DirectConnection);
connect(_tcp_socket, &QTcpSocket::disconnected, this, &MeasureSession::onClientDisconnected, Qt::DirectConnection);
connect(_tcp_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, &MeasureSession::onSocketError, Qt::DirectConnection);
// 开启线程事件循环(保持长连接,不退出线程)
exec();
// 线程退出后清理资源
_tcp_socket->close();
_tcp_socket->deleteLater();
}
void MeasureSession::onClientRequstData()
{
_requst_buffer->append(_tcp_socket->readAll());
while (true) {
// 读头
if (_requst_data_len == 0) {
if (_requst_buffer->size() < Protocol::HEAD_SIZE)
break;
QByteArray head = _requst_buffer->left(Protocol::HEAD_SIZE);
_requst_data_len = Protocol::UnpackDataLen(head);
_requst_buffer->remove(0, Protocol::HEAD_SIZE);
}
// 读满完整数据
if (_requst_buffer->size() >= _requst_data_len) {
QByteArray requst_data = _requst_buffer->left(_requst_data_len);
_requst_buffer->remove(0, _requst_data_len);
QLOG_INFO() << QStringLiteral(u"接收请求数据长度%1").arg(requst_data.size());
QThread* process_thread = QThread::create(&RequstDataProcesser::ProcessRequstData, _tcp_socket, requst_data);
connect(process_thread, &QThread::finished, process_thread, &QThread::deleteLater);
process_thread->start();
_requst_data_len = 0;
} else {
break;
}
}
}
void MeasureSession::onClientDisconnected()
{
QLOG_INFO() << QStringLiteral(u"客户端%1断开连接").arg(_tcp_socket->peerAddress().toString());
quit();
}
void MeasureSession::onSocketError(QAbstractSocket::SocketError error)
{
Q_UNUSED(error);
QLOG_INFO() << QStringLiteral(u"套接字错误:").arg(_tcp_socket->errorString());
quit();
}

View File

@ -3,8 +3,10 @@
#include <QStringList>
#include <QTcpServer>
#include <QTcpSocket>
#include <QThread>
class MeasureTask;
class RequstDataProcesser;
class MeasureServer : public QTcpServer
{
@ -12,14 +14,33 @@ class MeasureServer : public QTcpServer
public:
MeasureServer(QObject *parent = nullptr);
bool Start(quint16 port = 96966);
bool Start(quint16 port = 9999);
void Stop();
protected:
void incomingConnection(qintptr socketDescriptor) override;
void incomingConnection(qintptr socket_descriptor) override;
};
class MeasureSession : public QThread
{
Q_OBJECT
public:
MeasureSession(int socket_descriptor, QObject *parent = nullptr);
virtual ~MeasureSession();
void run() override;
private slots:
void onClientRequstData();
void onClientDisconnected();
void onSocketError(QAbstractSocket::SocketError error);
private:
MeasureTask* _measure_thread = nullptr;
int _socket_descriptor;
RequstDataProcesser * _tcp_socket;
QByteArray * _requst_buffer;
qint32 _requst_data_len;
};

View File

@ -0,0 +1,34 @@
#ifndef MEASURESERVICEPROTOCOL_H
#define MEASURESERVICEPROTOCOL_H
#include <QByteArray>
namespace Protocol {
// 固定协议头长度8字节
const int HEAD_SIZE = 8;
// 打包数据:添加长度头
inline QByteArray PackData(const QByteArray &data) {
QByteArray buffer;
buffer.resize(HEAD_SIZE);
// 前4字节 = 数据总长度
qint32 data_len = data.size();
memcpy(buffer.data(), &data_len, 4);
// 后4字节保留
qint32 reserve = 0xFFFFFFFF;
memcpy(buffer.data() + 4, &reserve, 4);
buffer.append(data);
return buffer;
}
// 解包:从头部获取数据长度
inline qint32 UnpackDataLen(const QByteArray &head) {
if (head.size() < HEAD_SIZE)
return 0;
qint32 len = 0;
memcpy(&len, head.constData(), 4);
return len;
}
}
#endif // MEASURESERVICEPROTOCOL_H

View File

@ -1,198 +0,0 @@
#include "MeasureTask.h"
#include <QDataStream>
#include "MeasureDeviceController.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QSqlDatabase>
#include <QFileInfo>
MeasureTask::MeasureTask(int socketDescriptor, QObject *parent)
: QThread(parent), socketDescriptor(socketDescriptor)
{
}
void MeasureTask::run()
{
QTcpSocket tcpSocket;
if (!tcpSocket.setSocketDescriptor(socketDescriptor)) {
return;
}
QByteArray buffer;
while (tcpSocket.waitForReadyRead(500)) {
buffer.append(tcpSocket.readAll());
}
if ( buffer.size() ) {
QDataStream requst_data_stream(buffer);
QString cmd_type, device_guid, cmd_data;
requst_data_stream >> cmd_type >> device_guid;
if ( cmd_type == "START" ) {
requst_data_stream >> cmd_data;
processStartMeasureCmd(&tcpSocket, device_guid, cmd_data);
} else if (cmd_type == "STOP") {
processStopMeasureCmd(&tcpSocket, device_guid);
} else if (cmd_type == "SET") {
requst_data_stream >> cmd_data;
processSetDeviceMeasureConfigParamsCmd(&tcpSocket, device_guid, cmd_data);
} else if (cmd_type == "CLEAR") {
processClearDataCmd(&tcpSocket, device_guid);
} else if (cmd_type == "DEVICE") {
processGetMeasureDeviceListCmd(&tcpSocket);
} else {
QByteArray replay_data;
QDataStream replay_data_stream(replay_data);
replay_data_stream << QString("UNKNOW") << false << QStringLiteral(u"未知请求");
tcpSocket.write(replay_data);
tcpSocket.flush();
}
} else {
QByteArray replay_data;
QDataStream replay_data_stream(replay_data);
replay_data_stream << QString("UNKNOW") << false << QStringLiteral(u"未知请求");
tcpSocket.write(replay_data);
tcpSocket.flush();
}
tcpSocket.disconnectFromHost();
tcpSocket.waitForDisconnected(1000);
}
void MeasureTask::processStartMeasureCmd(QTcpSocket* socket, const QString &device_guid, const QString &cmd_data)
{
QByteArray json_data = cmd_data.toUtf8();
QJsonDocument json_doc = QJsonDocument::fromJson(json_data);
if (json_doc.isNull()) {
return;
}
if (!json_doc.isObject()) {
return;
}
QVariantMap device_config_info = json_doc.object().toVariantMap();
if (!device_config_info.contains(QStringLiteral(u"ChannelConfig"))) {
return;
}
QVariantList channel_config_list = device_config_info[QStringLiteral(u"ChannelConfig")].toList();
if (channel_config_list.isEmpty()) {
return;
}
bool ok = true;
for (auto channel_config : channel_config_list) {
if (!channel_config.isValid())
continue;
QVariantMap channel_config_info = channel_config.toMap();
if (!channel_config_info.contains("BoardId") || !channel_config_info.contains("ChannelId"))
continue;
int board_id = channel_config_info["BoardId"].toInt();
int channel_id = channel_config_info["ChannelId"].toInt();
ok &= MeasureDeviceController::Instance()->SetDeviceMeasureConfigParams(device_guid, board_id, channel_id, channel_config_info);
QByteArray replay_data;
QDataStream replay_data_stream(replay_data);
if (!ok) {
replay_data_stream << QString("START") << ok << QStringLiteral(u"启动设置板卡%1通道%2测量参数失败").arg(board_id).arg(channel_id);
} else {
replay_data_stream << QString("START") << ok << QStringLiteral(u"启动设置板卡%1通道%2测量参数完成").arg(board_id).arg(channel_id);
}
socket->write(replay_data);
socket->flush();
ok &= MeasureDeviceController::Instance()->StartMeasure(device_guid, board_id, channel_id);
if (!ok) {
replay_data_stream << QString("START") << ok << QStringLiteral(u"启动板卡%1通道%2测量失败");
} else {
replay_data_stream << QString("START") << ok << QStringLiteral(u"启动板卡%1通道%2测量完成");
}
socket->write(replay_data);
socket->flush();
}
if (!ok) {
// MeasureDeviceController::Instance()->StopMeasure(device_guid);
return;
}
const QString& measure_data_gvf_filename = MeasureDeviceController::Instance()->GetMeasureGvfDataFilename();
if (measure_data_gvf_filename.isEmpty()) {
return;
}
QByteArray replay_data;
QDataStream replay_data_stream(replay_data);
replay_data_stream << QString("DATA") << true << measure_data_gvf_filename;
socket->write(replay_data);
socket->flush();
}
void MeasureTask::processStopMeasureCmd(QTcpSocket* socket, const QString &device_guid)
{
MeasureDeviceController::Instance()->StopMeasure(device_guid);
QByteArray replay_data;
QDataStream replay_data_stream(replay_data);
replay_data_stream << QString("STOP") << true << QStringLiteral(u"停止测量完成");
socket->write(replay_data);
socket->flush();
}
void MeasureTask::processSetDeviceMeasureConfigParamsCmd(QTcpSocket* socket, const QString &device_guid, const QString &cmd_data)
{
bool ok = true;
QByteArray json_data = cmd_data.toUtf8();
QJsonDocument json_doc = QJsonDocument::fromJson(json_data);
if (json_doc.isNull()) {
return;
}
if (!json_doc.isObject()) {
return;
}
QVariantMap device_config_info = json_doc.object().toVariantMap();
if (!device_config_info.contains(QStringLiteral(u"ChannelConfig"))) {
return;
}
QVariantList channel_config_list = device_config_info[QStringLiteral(u"ChannelConfig")].toList();
if (channel_config_list.isEmpty()) {
return;
}
for (auto channel_config : channel_config_list) {
if (!channel_config.isValid())
continue;
QVariantMap channel_config_info = channel_config.toMap();
if (!channel_config_info.contains("BoardId") || !channel_config_info.contains("ChannelId"))
continue;
int board_id = channel_config_info["BoardId"].toInt();
int channel_id = channel_config_info["ChannelId"].toInt();
ok &= MeasureDeviceController::Instance()->SetDeviceMeasureConfigParams(device_guid, board_id, channel_id, channel_config_info);
QByteArray replay_data;
QDataStream replay_data_stream(replay_data);
if (!ok) {
replay_data_stream << QString("SET") << ok << QStringLiteral(u"设置板卡%1通道%2测量参数失败").arg(board_id).arg(channel_id);
} else {
replay_data_stream << QString("SET") << ok << QStringLiteral(u"设置板卡%1通道%2测量参数完成").arg(board_id).arg(channel_id);
}
socket->write(replay_data);
socket->flush();
}
}
void MeasureTask::processClearDataCmd(QTcpSocket* socket, const QString &device_guid)
{
MeasureDeviceController::Instance()->ClearData(device_guid);
QByteArray replay_data;
QDataStream replay_data_stream(replay_data);
replay_data_stream << QString("CLEAR") << true << QStringLiteral(u"清除数据完成");
socket->write(replay_data);
socket->flush();
}
void MeasureTask::processGetMeasureDeviceListCmd(QTcpSocket* socket)
{
QStringList device_list = MeasureDeviceController::Instance()->GetMeasureDeviceList();
bool ok = !device_list.isEmpty();
QByteArray replay_data;
QDataStream replay_data_stream(replay_data);
replay_data_stream << QString("DEVICE");
if ( ok ) {
replay_data_stream << ok << device_list.size();
foreach (const QString& device_id, device_list) {
replay_data_stream << device_id;
}
} else {
replay_data_stream << ok;
}
socket->write(replay_data);
socket->flush();
}

View File

@ -1,30 +0,0 @@
#ifndef MEASURETASK_H
#define MEASURETASK_H
#include <QThread>
#include <QTcpSocket>
class MeasureTask : public QThread
{
Q_OBJECT
public:
MeasureTask(int socketDescriptor, QObject *parent = nullptr);
void run() override;
private:
void processStartMeasureCmd(QTcpSocket* socket, const QString& device_guid, const QString& cmd_data);
void processStopMeasureCmd(QTcpSocket* socket, const QString& device_guid);
void processSetDeviceMeasureConfigParamsCmd(QTcpSocket* socket, const QString& device_guid, const QString& cmd_data);
void processClearDataCmd(QTcpSocket* socket, const QString& device_guid);
void processGetMeasureDeviceListCmd(QTcpSocket* socket);
signals:
void error(QTcpSocket::SocketError socketError);
private:
int socketDescriptor;
};
#endif

220
src/RequstDataProcesser.cpp Normal file
View File

@ -0,0 +1,220 @@
#include "RequstDataProcesser.h"
#include "QsLogManage.h"
#include "MeasureDeviceController.h"
#include "MeasureServiceProtocol.h"
#include <QThread>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDataStream>
#include "SyncGvfFileDataTask.h"
RequstDataProcesser::RequstDataProcesser(QObject *parent)
: QTcpSocket{parent}
{
sync_gvf_data_task = new SyncGvfFileDataTask(this);
connect(sync_gvf_data_task, &SyncGvfFileDataTask::syncGvfData, this, &RequstDataProcesser::OnReplayClient/*, Qt::QueuedConnection*/);
connect(this, &RequstDataProcesser::stopSyncGvfFileDataTask, sync_gvf_data_task, &SyncGvfFileDataTask::OnStop);
}
RequstDataProcesser::~RequstDataProcesser()
{
QLOG_DEBUG() << QStringLiteral(u"~RequstDataProcesser");
}
void RequstDataProcesser::OnReplayClient(const QByteArray& replay_data)
{
if (!this->isOpen()) {
QLOG_WARN() << QStringLiteral(u"未连接,发送失败");
return;
}
QByteArray replay_buf = Protocol::PackData(replay_data);
this->write(replay_buf);
this->flush();
QLOG_DEBUG() << QStringLiteral(u"发送数据大小: %1 字节").arg(replay_buf.size());
}
void RequstDataProcesser::ProcessRequstData(const QByteArray& requst_data)
{
QDataStream requst_data_stream(requst_data);
QString cmd_type, device_guid, cmd_data;
requst_data_stream >> cmd_type >> device_guid;
if (cmd_type == "START") {
requst_data_stream >> cmd_data;
QLOG_INFO() << QStringLiteral(u"处理请求:") << cmd_type << device_guid << cmd_data;
processStartMeasureCmd(device_guid, cmd_data);
} else if (cmd_type == "STOP") {
QLOG_INFO() << QStringLiteral(u"处理请求:") << cmd_type << device_guid;
processStopMeasureCmd(device_guid);
} else if (cmd_type == "SET") {
requst_data_stream >> cmd_data;
QLOG_INFO() << QStringLiteral(u"处理请求:") << cmd_type << device_guid << cmd_data;
processSetDeviceMeasureConfigParamsCmd(device_guid, cmd_data);
} else if (cmd_type == "CLEAR") {
QLOG_INFO() << QStringLiteral(u"处理请求:") << cmd_type << device_guid;
processClearDataCmd(device_guid);
} else if (cmd_type == "DEVICE") {
QLOG_INFO() << QStringLiteral(u"处理请求:") << cmd_type << device_guid;
processGetMeasureDeviceListCmd();
} else {
QByteArray replay_data;
QDataStream replay_data_stream(&replay_data, QIODevice::Append);
replay_data_stream << QString("UNKNOW") << false << QStringLiteral(u"未知请求");
QMetaObject::invokeMethod(this, "OnReplayClient", Qt::QueuedConnection, Q_ARG(QByteArray, replay_data));
}
}
void RequstDataProcesser::processStartMeasureCmd(const QString& device_guid, const QString& cmd_data)
{
QByteArray json_data = cmd_data.toUtf8();
QJsonDocument json_doc = QJsonDocument::fromJson(json_data);
if (json_doc.isNull()) {
return;
}
if (!json_doc.isObject()) {
return;
}
QVariantMap device_config_info = json_doc.object().toVariantMap();
if (!device_config_info.contains(QStringLiteral(u"ChannelConfig"))) {
return;
}
QVariantList channel_config_list = device_config_info[QStringLiteral(u"ChannelConfig")].toList();
if (channel_config_list.isEmpty()) {
return;
}
QStringList errors;
for (auto channel_config : channel_config_list) {
if (!channel_config.isValid())
continue;
QVariantMap channel_config_info = channel_config.toMap();
if (!channel_config_info.contains("BoardId") || !channel_config_info.contains("ChannelId"))
continue;
int board_id = channel_config_info["BoardId"].toInt();
int channel_id = channel_config_info["ChannelId"].toInt();
if (!MeasureDeviceController::Instance()->SetDeviceMeasureConfigParams(device_guid, board_id, channel_id, channel_config_info)) {
const QString error = QStringLiteral(u"启动设置板卡%1通道%2测量参数失败").arg(board_id).arg(channel_id);
errors.append(error);
}
QThread::msleep(100);
}
for (auto channel_config : channel_config_list) {
if (!channel_config.isValid())
continue;
QVariantMap channel_config_info = channel_config.toMap();
if (!channel_config_info.contains("BoardId") || !channel_config_info.contains("ChannelId"))
continue;
int board_id = channel_config_info["BoardId"].toInt();
int channel_id = channel_config_info["ChannelId"].toInt();
if (!MeasureDeviceController::Instance()->StartMeasure(device_guid, board_id, channel_id)) {
const QString error = QStringLiteral(u"启动板卡%1通道%2测量失败").arg(board_id).arg(channel_id);
errors.append(error);
}
QThread::msleep(100);
}
QByteArray replay_data;
QDataStream replay_data_stream(&replay_data, QIODevice::Append);
if (!errors.isEmpty()) {
replay_data_stream << QString("START") << false << errors.join("\n");
QMetaObject::invokeMethod(this, "OnReplayClient", Qt::QueuedConnection, Q_ARG(QByteArray, replay_data));
} else {
const QString& measure_data_gvf_filename = MeasureDeviceController::Instance()->GetMeasureGvfDataFilename();
QString replay_info;
bool ok = measure_data_gvf_filename.isEmpty();
if (!ok) {
replay_info = QStringLiteral(u"测量数据GVF文件未找到");
} else {
replay_info = measure_data_gvf_filename;
sync_gvf_data_task->SetGvfFilename(measure_data_gvf_filename);
sync_gvf_data_task->start();
}
QByteArray replay_data;
QDataStream replay_data_stream(&replay_data, QIODevice::Append);
replay_data_stream << QString("START") << ok << replay_info;
QMetaObject::invokeMethod(this, "OnReplayClient", Qt::QueuedConnection, Q_ARG(QByteArray, replay_data));
}
sync_gvf_data_task->SetGvfFilename("D:/Workspace/EnergySpectrumAnalyerProject/TestData/GVHD__2025_10_16_16_00_39_653.gvf");
sync_gvf_data_task->start();
}
void RequstDataProcesser::processStopMeasureCmd(const QString& device_guid)
{
MeasureDeviceController::Instance()->StopMeasure(device_guid);
emit stopSyncGvfFileDataTask();
QByteArray replay_data;
QDataStream replay_data_stream(&replay_data, QIODevice::Append);
replay_data_stream << QString("STOP") << true << QStringLiteral(u"停止测量完成");
QMetaObject::invokeMethod(this, "OnReplayClient", Qt::QueuedConnection, Q_ARG(QByteArray, replay_data));
}
void RequstDataProcesser::processSetDeviceMeasureConfigParamsCmd(const QString& device_guid, const QString& cmd_data)
{
QByteArray json_data = cmd_data.toUtf8();
QJsonDocument json_doc = QJsonDocument::fromJson(json_data);
if (json_doc.isNull()) {
return;
}
if (!json_doc.isObject()) {
return;
}
QVariantMap device_config_info = json_doc.object().toVariantMap();
if (!device_config_info.contains(QStringLiteral(u"ChannelConfig"))) {
return;
}
QVariantList channel_config_list = device_config_info[QStringLiteral(u"ChannelConfig")].toList();
if (channel_config_list.isEmpty()) {
return;
}
QStringList errors;
for (auto channel_config : channel_config_list) {
if (!channel_config.isValid())
continue;
QVariantMap channel_config_info = channel_config.toMap();
if (!channel_config_info.contains("BoardId") || !channel_config_info.contains("ChannelId"))
continue;
int board_id = channel_config_info["BoardId"].toInt();
int channel_id = channel_config_info["ChannelId"].toInt();
if (!MeasureDeviceController::Instance()->SetDeviceMeasureConfigParams(device_guid, board_id, channel_id, channel_config_info)) {
const QString error = QStringLiteral(u"设置板卡%1通道%2测量参数失败").arg(board_id).arg(channel_id);
errors.append(error);
}
QThread::msleep(100);
}
QByteArray replay_data;
QDataStream replay_data_stream(&replay_data, QIODevice::Append);
bool ok = !errors.isEmpty();
if (!ok) {
replay_data_stream << QString("SET") << ok << errors.join("\n");
} else {
replay_data_stream << QString("SET") << ok << QStringLiteral(u"设置测量参数完成");
}
QMetaObject::invokeMethod(this, "OnReplayClient", Qt::QueuedConnection, Q_ARG(QByteArray, replay_data));
}
void RequstDataProcesser::processClearDataCmd(const QString& device_guid)
{
MeasureDeviceController::Instance()->ClearData(device_guid);
QByteArray replay_data;
QDataStream replay_data_stream(&replay_data, QIODevice::Append);
replay_data_stream << QString("CLEAR") << true << QStringLiteral(u"清除数据完成");
QMetaObject::invokeMethod(this, "OnReplayClient", Qt::QueuedConnection, Q_ARG(QByteArray, replay_data));
}
void RequstDataProcesser::processGetMeasureDeviceListCmd()
{
QStringList device_list = MeasureDeviceController::Instance()->GetMeasureDeviceList();
bool ok = !device_list.isEmpty();
QByteArray replay_data;
QDataStream replay_data_stream(&replay_data, QIODevice::Append);
replay_data_stream << QString("DEVICE");
if (ok) {
replay_data_stream << ok << device_list.size();
foreach (const QString& device_id, device_list) {
replay_data_stream << device_id;
}
} else {
replay_data_stream << ok << QStringLiteral(u"测量设备未找到");
}
QMetaObject::invokeMethod(this, "OnReplayClient", Qt::QueuedConnection, Q_ARG(QByteArray, replay_data));
}

35
src/RequstDataProcesser.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef REQUSTDATAPROCESSER_H
#define REQUSTDATAPROCESSER_H
#include <QObject>
#include <QTcpSocket>
class SyncGvfFileDataTask;
class RequstDataProcesser : public QTcpSocket
{
Q_OBJECT
public:
explicit RequstDataProcesser(QObject *parent = nullptr);
virtual ~RequstDataProcesser();
void ProcessRequstData(const QByteArray& requst_data);
public slots:
void OnReplayClient(const QByteArray& replay_data);
signals:
void stopSyncGvfFileDataTask();
private:
void processStartMeasureCmd(const QString& device_guid, const QString& cmd_data);
void processStopMeasureCmd(const QString& device_guid);
void processSetDeviceMeasureConfigParamsCmd(const QString& device_guid, const QString& cmd_data);
void processClearDataCmd( const QString& device_guid);
void processGetMeasureDeviceListCmd();
private:
SyncGvfFileDataTask* sync_gvf_data_task;
};
#endif // REQUSTDATAPROCESSER_H

View File

@ -0,0 +1,89 @@
#include "SyncGvfFileDataTask.h"
#include "QsLogManage.h"
#include <QByteArray>
#include <QDataStream>
#include <QDateTime>
#include <QFileInfo>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
SyncGvfFileDataTask::SyncGvfFileDataTask(QObject *parent)
: QThread{parent}, _b_stop(true)
{
}
SyncGvfFileDataTask::~SyncGvfFileDataTask()
{
_b_stop = true;
if ( this->isRunning() )
this->wait(3000);
QLOG_DEBUG() << QStringLiteral(u"~SyncGvfFileDataTask()");
}
void SyncGvfFileDataTask::SetGvfFilename(const QString &gvf_filename)
{
_gvf_filename = gvf_filename;
}
void SyncGvfFileDataTask::run()
{
if (_gvf_filename.isEmpty()) {
QLOG_WARN() << QStringLiteral(u"没有GVF测量数据文件");
return;
}
QFileInfo gvf_file_info(_gvf_filename);
if (!gvf_file_info.exists()) {
QLOG_WARN() << QStringLiteral(u"GVF测量数据文件%1不存在").arg(_gvf_filename);
return;
}
const QString& connect_name = gvf_file_info.baseName();
if ( QSqlDatabase::contains(connect_name) ) {
QSqlDatabase::removeDatabase(connect_name);
}
QSqlDatabase gvf_db = QSqlDatabase::addDatabase("QSQLITE", connect_name);
gvf_db.setDatabaseName(_gvf_filename);
if (!gvf_db.open()) {
QLOG_WARN() << QStringLiteral(u"打开读取连接失败: %1").arg(gvf_db.lastError().text());
return;
}
quint64 current_process_data_id = 0;
_b_stop = false;
while (!_b_stop) {
QSqlQuery query(gvf_db);
query.exec("SELECT recordnum FROM lmstatisticinfov2");
if (query.last()) {
quint64 record_num = query.value("recordnum").toULongLong();
QLOG_DEBUG() << QStringLiteral(u"测量数据记录总数: %1").arg(record_num);
}
query.exec(QString("SELECT id, data FROM lmdatainfov2 WHERE id > %1").arg(current_process_data_id ));
int data_record_count = 0;
while (bool(!_b_stop) && query.next()) {
quint64 id = query.value("id").toULongLong();
const QByteArray& data = query.value("data").toByteArray();
if (id > current_process_data_id)
current_process_data_id = id;
++data_record_count;
QByteArray gvf_data;
QDataStream replay_data_stream(&gvf_data, QIODevice::Append);
replay_data_stream << QString("GVF") << true << data.size();
replay_data_stream.writeRawData(data.data(), data.size());
QLOG_DEBUG() << QStringLiteral(u"GVFDATA: %1").arg(QString::fromUtf8(data.toHex().toUpper()));
emit syncGvfData(gvf_data);
QThread::sleep(1);
}
query.clear();
query.finish();
}
gvf_db.close();
QSqlDatabase::removeDatabase(connect_name);
QLOG_DEBUG() << QStringLiteral(u"SyncGvfFileDataTask执行完成退出");
}
void SyncGvfFileDataTask::OnStop()
{
_b_stop = true;
QLOG_DEBUG() << QStringLiteral(u"停止SyncGvfFileDataTask");
}

28
src/SyncGvfFileDataTask.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef SYNCGVFFILEDATATASK_H
#define SYNCGVFFILEDATATASK_H
#include <QObject>
#include <QThread>
class SyncGvfFileDataTask : public QThread
{
Q_OBJECT
public:
explicit SyncGvfFileDataTask(QObject *parent = nullptr);
virtual ~SyncGvfFileDataTask();
void SetGvfFilename(const QString& gvf_filename);
void run() override;
public slots:
void OnStop();
signals:
void syncGvfData(const QByteArray& data);
private:
QString _gvf_filename;
bool _b_stop;
};
#endif // SYNCGVFFILEDATATASK_H

View File

@ -2,23 +2,24 @@
#include "MeasureServer.h"
#include "QsLogManage.h"
#include <QCoreApplication>
#include <QThread>
int main(int argc, char* argv[])
{
QCoreApplication app(argc, argv);
// 创建日志记录器
QsLogManage::createLogger();
MeasureDeviceController::Instance()->SetInitFinishedHandler(
[&](bool init_ok) {
if (init_ok) {
MeasureServer measure_server;
if (!measure_server.Start()) {
QLOG_ERROR() << measure_server.errorString();
MeasureServer measure_server;
if (!measure_server.Start()) {
QLOG_ERROR() << QStringLiteral(u"测量服务启动失败:") + measure_server.errorString();
} else {
MeasureDeviceController::Instance()->SetInitFinishedHandler(
[&](bool init_ok) {
if (!init_ok) {
QLOG_ERROR() << QStringLiteral(u"未找到测量设备,测量服务程序退出.");
// app.exit(EXIT_FAILURE);
}
} else {
app.exit(EXIT_FAILURE);
}
});
MeasureDeviceController::Instance()->InitFindMeasureDevice();
});
MeasureDeviceController::Instance()->InitFindMeasureDevice();
}
return app.exec();
}

View File

@ -8,7 +8,6 @@ msvc {
QMAKE_CXXFLAGS += /utf-8
}
include($${PWD}/../Common.pri)
include($${PROJECT_DIR}/3rdlib/QsLog/QsLog.pri)
include($${PROJECT_DIR}/3rdlib/csv/csv.pri)
@ -22,14 +21,17 @@ UI_DIR = $${BUILD_UI}/$${TARGET}/ui
SOURCES += \
$${PWD}/MeasureServer.cpp \
$${PWD}/MeasureTask.cpp \
$${PWD}/main.cpp \
MeasureDeviceController.cpp
$${PWD}/MeasureDeviceController.cpp \
$${PWD}/RequstDataProcesser.cpp \
SyncGvfFileDataTask.cpp
HEADERS += \
$${PWD}/MeasureServer.h \
$${PWD}/MeasureTask.h \
MeasureDeviceController.h
$${PWD}/MeasureDeviceController.h \
$${PWD}/MeasureServiceProtocol.h \
$${PWD}/RequstDataProcesser.h \
SyncGvfFileDataTask.h
DEFINES += ENABLE_DEBUG