|
|
|
|
#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 true:是闰年;false:不是闰年
|
|
|
|
|
*/
|
|
|
|
|
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 true:是合法的日;false:不是合法的日
|
|
|
|
|
*/
|
|
|
|
|
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, "提示", "处理结束!!!");
|
|
|
|
|
}
|