You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

372 lines
11 KiB
C++

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QByteArray>
#include <QDataStream>
#include <QDate>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QTime>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
ui->hourSpinBox->setMaximum(23);
ui->minuteSpinBox->setMaximum(59);
ui->secondSpinBox->setMaximum(59);
folderPath = "";
}
MainWindow::~MainWindow() { delete ui; }
void MainWindow::ReadDat(QString fileName) {
int year = ui->yearSpinBox->value();
int month = ui->monthSpinBox->value();
int day = ui->daySpinBox->value();
int hour = ui->hourSpinBox->value();
int minute = ui->minuteSpinBox->value();
int second = ui->secondSpinBox->value();
QTime time(hour, minute, second);
QDate date(year + 2000, month, day);
QDateTime targetTime(date, time);
// 转化为16进制
uint8_t hexYear = IntToHex(year);
uint8_t hexMonth = IntToHex(month);
uint8_t hexDay = IntToHex(day);
uint8_t hexHour = IntToHex(hour);
uint8_t hexMinute = IntToHex(minute);
uint8_t hexSecond = IntToHex(second);
// QString filename = outputDir+"/"+fileName;
// // 一个示例日期年月日分别为2023年、12月、3日
// QDate date(year+2000, month, day);
// // 将日期格式化为yymmdd
// QString formattedDate = date.toString("yyyyMMdd");
// //修改文件名的时间信息
// QString f1 = fileName;
// f1.remove(11,f1.length()-11);
// QString f2 = fileName;
// f2.remove(0,11+8);
// QString str = f1+formattedDate+f2;
QString outputFileName =
GetOutputFileName(fileName, year, month, day, hour, minute, second);
// 创建修改后的dat文件
QFile writeFile(outputDir + "/" + outputFileName);
QDataStream outStream;
if (writeFile.open(QIODevice::WriteOnly)) {
// 创建数据流,用于写入二进制数据
// outStream = QDataStream(&writeFile);
outStream.setDevice(&writeFile);
outStream.setByteOrder(QDataStream::LittleEndian);
}
int len = 265;
quint8 *data = new quint8[len];
QFile file1 = QFile(folderPath + "/" + fileName);
// QFile file1 = QFile("E:\\dat\\output\\下行遥测_0_1_0_20230619230109.dat");
file1.open(QIODevice::ReadOnly);
QDataStream readStream = QDataStream(&file1);
readStream.setVersion(QDataStream::Qt_5_15); // 设置数据流的版本
readStream.setByteOrder(QDataStream::LittleEndian);
int i = 0;
quint8 *content = new quint8[28]; // 创建一个28字节的数据缓冲区
// int sub1 = 0;
// int sub2 = 0;
bool bFirstTime = true;
qint64 offsetTime = 0;
while (!readStream.atEnd()) {
readStream.readRawData((char *)data, len); // 读取一帧
QTime time(data[5], data[6], data[7]);
QDate date(int(data[2]) + 2000, data[3], data[4]);
QDateTime curTime(date, time);
if (bFirstTime) {
offsetTime = curTime.secsTo(targetTime);
bFirstTime = false;
}
QTime tmp0 = curTime.time();
curTime = curTime.addSecs(offsetTime);
QTime tmp1 = curTime.time();
// i++;
// 四个子帧解析
// int id1 = 16;
// int id2 = id1+32;
// int id3 = id2+32;
// int id4 = id3+32;
int startID = 16;
for (int var = 0; var < 4; ++var) {
startID = 16 + 32 * var;
quint8 zhenID = data[startID + 4];
if (zhenID == 0x87 || zhenID == 0x89 || zhenID == 0x8A) {
if (data[startID + 17] == 0x02) // 子帧2
{
// QTime time(data[startID + 21], data[startID + 22],
// data[startID + 23]);
// QDate date(int(data[startID + 20]) + 2000, data[startID + 19],
// data[startID + 18]);
// QDateTime tmpTime(date, time);
// tmpTime = tmpTime.addSecs(offsetTime);
// 修改UTC年月日数据
if (hexDay > 0)
data[startID + 18] = hexDay;
if (hexMonth > 0)
data[startID + 19] = hexMonth;
if (hexYear > 0)
data[startID + 20] = hexYear;
// // 修改UTC时分秒数据
// if (hexHour > 0)
// data[startID + 21] = IntToHex(tmpTime.time().hour());
// if (hexMinute > 0)
// data[startID + 22] = IntToHex(tmpTime.time().minute());
// if (hexSecond > 0)
// data[startID + 23] = IntToHex(tmpTime.time().second());
// 计算CRC16校验位
for (int i = 0; i < 28; i++) // 提取数据帧内容
{
content[i] = data[startID + 2 + i];
}
quint16 crc = GetCrcSum(content, 28); // 计算校验码
// 提取高位和低位
quint8 highByte = static_cast<quint8>((crc >> 8) & 0xFF);
quint8 lowByte = static_cast<quint8>(crc & 0xFF);
// 修改CRC校验位
data[startID + 30] = lowByte;
data[startID + 31] = highByte;
}
}
}
// 修改系统时间戳
if (hexYear > 0)
data[2] = hexYear;
if (hexMonth > 0)
data[3] = hexMonth;
if (hexDay > 0)
data[4] = hexDay;
if (hexHour > 0)
data[5] = IntToHex(curTime.time().hour());
if (hexMinute > 0)
data[6] = IntToHex(curTime.time().minute());
if (hexSecond > 0)
data[7] = IntToHex(curTime.time().second());
// 修改最后校验位
data[len - 1] = GetDataCheckCRC(data, len);
// 写入文件
outStream.writeRawData((char *)data, len);
}
file1.close();
writeFile.close();
// qDebug()<<"*********************i:"<<i;
}
uint8_t MainWindow::IntToHex(int data) {
// 将十进制整数转换为十六进制表示
QByteArray hexData = QByteArray::number(data, 16);
// 将十六进制表示转换为 uint8_t 类型
bool ok;
return hexData.toUInt(&ok, 16);
}
/*******************************************************************************
GetCrcSum
CRC
CRC
*******************************************************************************/
quint16 MainWindow::GetCrcSum(quint8 *dataptr, quint16 len) {
qint16 count = 0;
quint8 C0 = 0, C1 = 0, Y0 = 0, Y1 = 0, Z0 = 0, Z1 = 0;
C0 = C1 = Y0 = Y1 = Z0 = Z1 = 0;
while (count < len) {
Y0 = (CRCLIST[2 * (*dataptr)] ^ C1) & 0x00FF;
Y1 = (CRCLIST[2 * (*dataptr) + 1]) & 0x00FF;
Z0 = CRCLIST[2 * C0] & 0x00FF;
Z1 = CRCLIST[2 * C0 + 1] & 0x00FF;
C0 = (Y0 ^ Z0) & 0x00FF;
C1 = (Y1 ^ Z1) & 0x00FF;
dataptr++;
count++;
}
return (C0 + C1 * 256); /* return crc result */
}
quint8 MainWindow::GetDataCheckCRC(quint8 *dataptr, quint16 len) {
quint8 sum = 0;
for (int i = 0; i < 264; i++) {
sum += quint8(dataptr[i]);
}
return quint8(~(sum & 0xFF) + 1);
}
/**
*
*
* @param year
* @return truefalse
*/
bool MainWindow::isLeapYear(int year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
return true;
} else {
return false;
}
}
/**
*
*
* @param year
* @param month
* @param day
* @return truefalse
*/
bool MainWindow::isValidDay(int year, int month, int day) {
if (month == 2) {
if (isLeapYear(year)) {
if (day >= 1 && day <= 29) {
return true;
}
} else {
if (day >= 1 && day <= 28) {
return true;
}
}
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
if (day >= 1 && day <= 30) {
return true;
}
} else {
if (day >= 1 && day <= 31) {
return true;
}
}
return false;
}
QString MainWindow::GetOutputFileName(QString fileName, int year, int month,
int day, int hour, int minute,
int second) {
// QString str = "下行遥测_0_17_0_20221114024453.dat";
QStringList strList = fileName.split("_");
QString endstr = strList.constLast();
QString lastStr = endstr.mid(14, -1);
if (year == 0)
year = endstr.mid(0, 4).toInt() - 2000;
// QString year0 = endstr.mid(0,4);
if (month == 0)
month = endstr.mid(4, 2).toInt();
if (day == 0)
day = endstr.mid(6, 2).toInt();
// QString month = endstr.mid(4,2);
// QString day = endstr.mid(6,2);
if (hour == 0)
hour = endstr.mid(8, 2).toInt();
if (minute == 0)
minute = endstr.mid(10, 2).toInt();
if (second == 0)
second = endstr.mid(12, 2).toInt();
// 一个示例日期年月日分别为2023年、12月、3日
QDate date(year + 2000, month, day);
// 将日期格式化为yymmdd
QString formattedDate = date.toString("yyyyMMdd");
QTime time(hour, minute, second);
QString formattedTime = time.toString("hhmmss");
QString outputFileName = "";
strList.removeLast();
strList.append(formattedDate + formattedTime);
outputFileName = strList.join("_") + lastStr;
// for (int var = 0; var < strList.length()-2; ++var) {
// outputFileName += strList.at(var);
// }
return outputFileName;
}
void MainWindow::on_openDirBtn_clicked() {
// 创建一个QFileDialog对象
QFileDialog dialog;
// 设置对话框的标题
dialog.setWindowTitle("Select Folder");
// 设置对话框模式为选择文件夹
dialog.setFileMode(QFileDialog::Directory);
// 打开对话框
if (dialog.exec()) {
// 获取用户选择的文件夹路径
folderPath = dialog.selectedFiles().at(0);
qDebug() << "Selected Folder: " << folderPath;
} else {
qDebug() << "User canceled the operation.";
}
}
void MainWindow::CreateDir() {
// 创建一个QDir对象
QDir dir;
outputDir = folderPath + "/output";
// 设置目录路径
dir.setPath(outputDir);
// 创建文件夹
if (dir.mkpath(outputDir)) {
qDebug() << "Folder created successfully.";
} else {
qDebug() << "Failed to create folder.";
}
// QDir directory(folderPath+"/output");
}
void MainWindow::on_startModifyBtn_clicked() {
int year = ui->yearSpinBox->value();
int month = ui->monthSpinBox->value();
int day = ui->daySpinBox->value();
if (year <= 0 && month <= 0 && day <= 0) {
QMessageBox::information(NULL, "提示", "请设置要修改的年月日!!!");
return;
}
if (folderPath == "") {
QMessageBox::information(NULL, "提示", "请先设置文件夹!!!");
return;
}
// 检查Day是否正确
if (day > 0 && !isValidDay(year + 2000, month, day)) {
QMessageBox::information(NULL, "提示", "日期有误,请重新设置!!!");
return;
}
// 创建一个 QDir 对象
QDir directory(folderPath);
// 获取文件夹中的所有文件
QStringList files = directory.entryList(QDir::Files);
int numFiles = files.length();
if (numFiles == 0) {
QMessageBox::information(NULL, "提示", "该文件夹没有dat文件!!!");
return;
}
// 新建output文件夹
CreateDir();
// 开始处理
for (int n = 0; n < numFiles; ++n) {
ReadDat(files.at(n));
}
QMessageBox::information(NULL, "提示", "处理结束!!!");
}